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 2019/08/19 14:13:31 UTC

[oodt] branch development updated: [OODT-1010] Improve JAXRS REST APIs (#96)

This is an automated email from the ASF dual-hosted git repository.

magicaltrout pushed a commit to branch development
in repository https://gitbox.apache.org/repos/asf/oodt.git


The following commit(s) were added to refs/heads/development by this push:
     new 14bf994  [OODT-1010] Improve JAXRS REST APIs (#96)
14bf994 is described below

commit 14bf99424a03bdcd0459a11ca4660070d7491635
Author: Nadeeshan Gimhana <gi...@cse.mrt.ac.lk>
AuthorDate: Mon Aug 19 19:43:27 2019 +0530

    [OODT-1010] Improve JAXRS REST APIs (#96)
    
    * [OODT-1011] Use Error Payloads for exception handling
    
    * [OODT-1010] Add ProductPage related JAX-RS Rest APIs
    
    * Replace deprecated addMetadata(java.util.Hashtable) with addMetadata(java.util.HashMap) in jaxrs.resources tests
    
    * Update fmprod/pom.xml with cxf-rt-transports-http-jetty
    
    * [OODT-1010] Allow CORS Hearders for FMProd REST APIs
    
    * Rename getNextPage method
    
    * Update code styles
    
    * Clean Temp_build files accidently commited
    
    * Replace java.util.logger with slf4j logger
---
 core/pom.xml                                       |   5 +
 webapp/fmprod/pom.xml                              |   4 +
 .../oodt/cas/product/jaxrs/enums/ErrorType.java    |  68 ++++
 .../cas/product/jaxrs/errors/ErrorMessage.java     |  80 ++++
 .../BadRequestExceptionMapper.java                 |  53 +++
 .../CasProductExceptionMapper.java                 |  50 +++
 .../InternalServerErrorExceptionMapper.java        |  51 +++
 .../exceptionmappers/NotFoundExceptionMapper.java  |  53 +++
 .../jaxrs/exceptions/BadRequestException.java      |  24 +-
 .../exceptions/InternalServerErrorException.java   |  24 +-
 .../jaxrs/exceptions/NotFoundException.java        |  24 +-
 .../cas/product/jaxrs/exceptions/package-info.java |   7 +-
 .../oodt/cas/product/jaxrs/filters/CORSFilter.java |  80 ++++
 .../product/jaxrs/resources/FMStatusResource.java  |  54 +++
 .../jaxrs/resources/ProductPageResource.java       | 159 ++++++++
 .../jaxrs/services/CasProductJaxrsService.java     | 362 ++++++++---------
 .../jaxrs/services/FileManagerJaxrsServiceV2.java  | 434 +++++++++++++++++++++
 webapp/fmprod/src/main/webapp/WEB-INF/web.xml      |  22 +-
 .../jaxrs/resources/DatasetResourceTest.java       |  10 +-
 .../jaxrs/resources/MetadataResourceTest.java      |   6 +-
 .../jaxrs/resources/ProductPageResourceTest.java   | 158 ++++++++
 .../jaxrs/resources/ProductResourceTest.java       |   6 +-
 .../jaxrs/resources/TransferResourceTest.java      |   6 +-
 .../jaxrs/resources/TransfersResourceTest.java     |  10 +-
 .../oodt/cas/product/jaxrs_rest/RestAPITest.java   |  45 +++
 25 files changed, 1533 insertions(+), 262 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index fa86caa..6a6621f 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -286,6 +286,11 @@ the License.
       </dependency>
       <dependency>
         <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-rt-transports-http-jetty</artifactId>
+        <version>3.1.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-frontend-jaxrs</artifactId>
         <version>3.1.6</version>
       </dependency>
diff --git a/webapp/fmprod/pom.xml b/webapp/fmprod/pom.xml
index c817559..54f1d0c 100644
--- a/webapp/fmprod/pom.xml
+++ b/webapp/fmprod/pom.xml
@@ -83,6 +83,10 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-transports-http-jetty</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
     </dependency>
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/enums/ErrorType.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/enums/ErrorType.java
new file mode 100644
index 0000000..2a2339b
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/enums/ErrorType.java
@@ -0,0 +1,68 @@
+/*
+ * 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.product.jaxrs.enums;
+
+/**
+ * This is the Enumeration file for storing HTTP Exception types. Use these constants instead of
+ * hardcoding errors in REST API implementations
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+public enum ErrorType {
+  BAD_REQUEST_EXCEPTION("Malformed message"),
+  BAD_REQUEST_EXCEPTION_REFERENCE_RESOURCE(
+      "This URL requires a productId query parameter with a product ID value,"
+          + " e.g. /reference?productId=1787a257-df87-11e2-8a2d-e3f6264e86c5"),
+
+  BAD_REQUEST_EXCEPTION_PRODUCT_RESOURCE(
+      "Failed to load resource: the server responded with a status of 400"),
+  BAD_REQUEST_EXCEPTION_DATASET_RESOURCE(
+      "This URL requires a productTypeId query parameter and either a "
+          + "product type ID value or 'ALL' for all product types"),
+
+  BAD_REQUEST_EXCEPTION_TRANSFER_RESOURCE(
+      "This URL requires a dataStoreRef query parameter "
+          + "and a data store reference value, e.g. /transfer?dataStoreRef=file:/repository/test.txt/test.txt"),
+
+  INTERNAL_SERVER_ERROR("General Server Error"),
+
+  NOT_FOUND_EXCEPTION("Couldn’t find resource"),
+  NOT_FOUND_EXCEPTION_TRANSFER_RESOURCE(
+      "Unable to find a current file transfer status for data store reference: "),
+
+  CAS_PRODUCT_EXCEPTION_FILEMGR_CLIENT_UNAVILABLE(
+      "Unable to get the file manager client from the servlet context."),
+  CAS_PRODUCT_EXCEPTION_FILEMGR_WORKING_DIR_UNAVILABLE(
+      "Unable to get the file manager's" + " working directory from the servlet context.");
+
+  private String errorType;
+
+  ErrorType(String errorType) {
+    this.errorType = errorType;
+  }
+
+  /** @return the errorType */
+  public String getErrorType() {
+    return errorType;
+  }
+
+  /** @param errorType the errorType to set */
+  public void setErrorType(String errorType) {
+    this.errorType = errorType;
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/errors/ErrorMessage.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/errors/ErrorMessage.java
new file mode 100644
index 0000000..73ee65a
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/errors/ErrorMessage.java
@@ -0,0 +1,80 @@
+/*
+ * 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.product.jaxrs.errors;
+
+import javax.xml.bind.annotation.XmlRootElement;
+/**
+ * This is the Corresponding JAVA object for HTTP exception response payload
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@XmlRootElement
+public class ErrorMessage {
+
+  /** Status code = 400, 405, 500 etc */
+  private int errorStatusCode;
+
+  /** Basic Description for the Error = InternalServerException etc. * */
+  private String errorType;
+
+  /** More Information regarding the thrown exception = Reason for exception in Server side * */
+  private String exception;
+
+  public ErrorMessage() {}
+
+  public ErrorMessage(int errorStatusCode, String errorType, String exception) {
+    this.setErrorStatusCode(errorStatusCode);
+    this.setErrorType(errorType);
+    this.setException(exception);
+  }
+
+  public ErrorMessage(int errorStatusCode, String message) {
+    this.setErrorStatusCode(errorStatusCode);
+    this.setErrorType(message);
+  }
+
+  /** @return the errorStatusCode */
+  public int getErrorStatusCode() {
+    return errorStatusCode;
+  }
+
+  /** @param errorStatusCode the errorStatusCode to set */
+  public void setErrorStatusCode(int errorStatusCode) {
+    this.errorStatusCode = errorStatusCode;
+  }
+
+  /** @return the errorType */
+  public String getErrorType() {
+    return errorType;
+  }
+
+  /** @param errorType the errorType to set */
+  public void setErrorType(String errorType) {
+    this.errorType = errorType;
+  }
+
+  /** @return the exception */
+  public String getException() {
+    return exception;
+  }
+
+  /** @param exception the exception to set */
+  public void setException(String exception) {
+    this.exception = exception;
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/BadRequestExceptionMapper.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/BadRequestExceptionMapper.java
new file mode 100644
index 0000000..c81a472
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/BadRequestExceptionMapper.java
@@ -0,0 +1,53 @@
+/*
+ * 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.product.jaxrs.exceptionmappers;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.apache.oodt.cas.product.jaxrs.enums.ErrorType;
+import org.apache.oodt.cas.product.jaxrs.errors.ErrorMessage;
+import org.apache.oodt.cas.product.jaxrs.exceptions.BadRequestException;
+
+/**
+ * This is an exception mapper which maps "BadRequestException" to "ErrorMessage JSON payload"
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@Provider
+public class BadRequestExceptionMapper implements ExceptionMapper<BadRequestException> {
+
+  /** Maps BadRequestException to HTTP Response **/
+  @Override
+  public Response toResponse(BadRequestException exception) {
+
+    /** Initialising ErrorMessage Entity for Mapping to Response **/
+    ErrorMessage errorMessageEntity =
+        new ErrorMessage(
+            Response.Status.BAD_REQUEST.getStatusCode(),
+            ErrorType.BAD_REQUEST_EXCEPTION.getErrorType(),
+            exception.getMessage());
+
+    /** Maps Error Status 400 to Response **/
+    return Response.status(Response.Status.BAD_REQUEST)
+        .entity(errorMessageEntity)
+        .type(MediaType.APPLICATION_JSON)
+        .build();
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/CasProductExceptionMapper.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/CasProductExceptionMapper.java
new file mode 100644
index 0000000..c610f74
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/CasProductExceptionMapper.java
@@ -0,0 +1,50 @@
+/*
+ * 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.product.jaxrs.exceptionmappers;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.apache.oodt.cas.product.exceptions.CasProductException;
+import org.apache.oodt.cas.product.jaxrs.errors.ErrorMessage;
+
+/**
+ * This is an exception mapper which maps "BadRequestException" to "ErrorMessage JSON payload"
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@Provider
+public class CasProductExceptionMapper implements ExceptionMapper<CasProductException> {
+
+  /** Maps CasProductException to HTTP Response **/
+  @Override
+  public Response toResponse(CasProductException exception) {
+
+    /** Initialising ErrorMessage Entity for Mapping to Response **/
+    ErrorMessage errorMessageEntity =
+        new ErrorMessage(
+            Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), exception.getMessage());
+
+    /** Maps Error Status 500 to Response **/
+    return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+        .entity(errorMessageEntity)
+        .type(MediaType.APPLICATION_JSON)
+        .build();
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/InternalServerErrorExceptionMapper.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/InternalServerErrorExceptionMapper.java
new file mode 100644
index 0000000..763066d
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/InternalServerErrorExceptionMapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.product.jaxrs.exceptionmappers;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.apache.oodt.cas.product.jaxrs.errors.ErrorMessage;
+import org.apache.oodt.cas.product.jaxrs.exceptions.InternalServerErrorException;
+
+/**
+ * This is an exception mapper which maps "InternalServerException" to "ErrorMessage JSON payload"
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@Provider
+public class InternalServerErrorExceptionMapper
+    implements ExceptionMapper<InternalServerErrorException> {
+
+  /** Maps InternalServerException to HTTP Response **/
+  @Override
+  public Response toResponse(InternalServerErrorException exception) {
+
+    /** Initialising ErrorMessage Entity for Mapping to Response **/
+    ErrorMessage errorMessageEntity =
+        new ErrorMessage(
+            Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), exception.getMessage());
+
+    /** Maps Error Status 500 to Response **/
+    return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+        .entity(errorMessageEntity)
+        .type(MediaType.APPLICATION_JSON)
+        .build();
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/NotFoundExceptionMapper.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/NotFoundExceptionMapper.java
new file mode 100644
index 0000000..7a91e3c
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptionmappers/NotFoundExceptionMapper.java
@@ -0,0 +1,53 @@
+/*
+ * 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.product.jaxrs.exceptionmappers;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.apache.oodt.cas.product.jaxrs.enums.ErrorType;
+import org.apache.oodt.cas.product.jaxrs.errors.ErrorMessage;
+import org.apache.oodt.cas.product.jaxrs.exceptions.NotFoundException;
+
+/**
+ * This is an exception mapper which maps "NotFoundException" to "ErrorMessage JSON payload"
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@Provider
+public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {
+
+  // Maps NotFoundException to HTTP Response
+  @Override
+  public Response toResponse(NotFoundException exception) {
+
+    // Initialising ErrorMessage Entity for Mapping to Response
+    ErrorMessage errorMessageEntity =
+        new ErrorMessage(
+            Response.Status.NOT_FOUND.getStatusCode(),
+            ErrorType.NOT_FOUND_EXCEPTION.getErrorType(),
+            exception.getMessage());
+
+    // Maps Error Status 404 to Response
+    return Response.status(Response.Status.NOT_FOUND)
+        .entity(errorMessageEntity)
+        .type(MediaType.APPLICATION_JSON)
+        .build();
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/BadRequestException.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/BadRequestException.java
index 2e2de7a..f76bd6f 100644
--- a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/BadRequestException.java
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/BadRequestException.java
@@ -13,33 +13,29 @@
  * 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.product.jaxrs.exceptions;
 
 import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 
 /**
- * This type of exception returns an HTTP 'bad request' response (status code
- * 400) with an additional message.
+ * This type of exception returns an HTTP 'bad request' response (status code 400) with an
+ * additional message.
+ *
  * @author rlaidlaw
  * @version $Revision$
  */
-public class BadRequestException extends WebApplicationException
-{
-  // Auto-generated ID for serialization.
+public class BadRequestException extends WebApplicationException {
+  /** Auto-generated ID for serialization. **/
   private static final long serialVersionUID = -705065311316100022L;
 
   /**
-   * Constructor that adds a message to the 'bad request' (status code 400)
-   * HTTP response.
+   * Constructor that adds a message to the 'bad request' (status code 400) HTTP response.
+   *
    * @param message the message to add to the response
    */
-  public BadRequestException(String message)
-  {
-    super(Response.status(Response.Status.BAD_REQUEST).entity(message)
-      .type(MediaType.TEXT_PLAIN).build());
+  public BadRequestException(String message) {
+    super(message);
   }
 }
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/InternalServerErrorException.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/InternalServerErrorException.java
index 5af0842..c7841cf 100644
--- a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/InternalServerErrorException.java
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/InternalServerErrorException.java
@@ -13,33 +13,29 @@
  * 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.product.jaxrs.exceptions;
 
 import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 
 /**
- * This type of exception returns an HTTP 'internal server error' response
- * (status code 500) with an additional message.
+ * This type of exception returns an HTTP 'internal server error' response (status code 500) with an
+ * additional message.
+ *
  * @author rlaidlaw
  * @version $Revision$
  */
-public class InternalServerErrorException extends WebApplicationException
-{
-  // Auto-generated ID for serialization.
+public class InternalServerErrorException extends WebApplicationException {
+  /** Auto-generated ID for serialization. **/
   private static final long serialVersionUID = -6132240509391531373L;
 
   /**
-   * Constructor that adds a message to the 'internal server error' (status code
-   * 500) HTTP response.
+   * Constructor that adds a message to the 'internal server error' (status code 500) HTTP response.
+   *
    * @param message the message to add to the response
    */
-  public InternalServerErrorException(String message)
-  {
-    super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(message)
-      .type(MediaType.TEXT_PLAIN).build());
+  public InternalServerErrorException(String message) {
+    super(message);
   }
 }
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/NotFoundException.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/NotFoundException.java
index 108ed97..0533a50 100644
--- a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/NotFoundException.java
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/NotFoundException.java
@@ -13,33 +13,29 @@
  * 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.product.jaxrs.exceptions;
 
 import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 
 /**
- * This type of exception returns an HTTP 'not found' response (status code 404)
- * with an additional message.
+ * This type of exception returns an HTTP 'not found' response (status code 404) with an additional
+ * message.
+ *
  * @author rlaidlaw
  * @version $Revision$
  */
-public class NotFoundException extends WebApplicationException
-{
-  // Auto-generated ID for serialization.
+public class NotFoundException extends WebApplicationException {
+  /** Auto-generated ID for serialization. **/
   private static final long serialVersionUID = -3835077083758525919L;
 
   /**
-   * Constructor that adds a message to the 'not found' (status code 404)
-   * HTTP response.
+   * Constructor that adds a message to the 'not found' (status code 404) HTTP response.
+   *
    * @param message the message to add to the response
    */
-  public NotFoundException(String message)
-  {
-    super(Response.status(Response.Status.NOT_FOUND).entity(message)
-      .type(MediaType.TEXT_PLAIN).build());
+  public NotFoundException(String message) {
+    super(message);
   }
 }
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/package-info.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/package-info.java
index 7a69729..582f782 100644
--- a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/package-info.java
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/exceptions/package-info.java
@@ -13,11 +13,12 @@
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
-*/
+ */
 
 /**
- * Contains classes that extend javax.ws.rs.WebApplicationException to provide
- * specific response status codes and messages.
+ * Contains classes that extend javax.ws.rs.WebApplicationException to provide specific response
+ * status codes and messages.
+ *
  * @author rlaidlaw
  * @version $Revision$
  */
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/filters/CORSFilter.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/filters/CORSFilter.java
new file mode 100644
index 0000000..b591183
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/filters/CORSFilter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.product.jaxrs.filters;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.ext.Provider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CORS Filter class for Proposing Apache OODT-2.0 FileManager REST-APIs This is the CORS
+ * (Cross-origin Resource Sharing) Filter class for FMProd REST APIs
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@Provider
+public class CORSFilter implements Filter {
+
+  private static Logger logger = LoggerFactory.getLogger(CORSFilter.class);
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {}
+
+  /**
+   * @param servletRequest
+   * @param servletResponse
+   * @param filterChain
+   * @throws IOException
+   * @throws ServletException
+   */
+  @Override
+  public void doFilter(
+      ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+      throws IOException, ServletException {
+    HttpServletRequest request = (HttpServletRequest) servletRequest;
+    logger.debug("CORSFilter HTTP Request: ",request.getMethod());
+
+    /** Authorize (allow) all domains to consume the content **/
+    ((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Origin", "*");
+    ((HttpServletResponse) servletResponse)
+        .addHeader("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD, PUT, POST");
+
+    HttpServletResponse resp = (HttpServletResponse) servletResponse;
+
+    /** For HTTP OPTIONS verb/method reply with ACCEPTED status code -- per CORS handshake **/
+    if (request.getMethod().equals("OPTIONS")) {
+      resp.setStatus(HttpServletResponse.SC_ACCEPTED);
+      return;
+    }
+
+    /** pass the request along the filter chain **/
+    filterChain.doFilter(request, servletResponse);
+  }
+
+  @Override
+  public void destroy() {}
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/resources/FMStatusResource.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/resources/FMStatusResource.java
new file mode 100644
index 0000000..1c6af36
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/resources/FMStatusResource.java
@@ -0,0 +1,54 @@
+/*
+ * 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.product.jaxrs.resources;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * A JAX-RS resource representing a FileManager Status and URL.
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@XmlRootElement(name = "fmStatus")
+@XmlType(propOrder = {"url", "status"})
+@XmlAccessorType(XmlAccessType.NONE)
+public class FMStatusResource {
+
+  private String url;
+  private boolean status;
+
+  public FMStatusResource() {}
+
+  public FMStatusResource(String url, boolean status) {
+    this.url = url;
+    this.status = status;
+  }
+
+  @XmlElement(name = "status")
+  public boolean getStatus() {
+    return status;
+  }
+
+  @XmlElement(name = "url")
+  public String getUrl() {
+    return this.url;
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/resources/ProductPageResource.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/resources/ProductPageResource.java
new file mode 100644
index 0000000..2cb96dc
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/resources/ProductPageResource.java
@@ -0,0 +1,159 @@
+/*
+ * 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.product.jaxrs.resources;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.oodt.cas.filemgr.structs.Product;
+import org.apache.oodt.cas.filemgr.structs.ProductPage;
+import org.apache.oodt.cas.filemgr.structs.Reference;
+import org.apache.oodt.cas.metadata.Metadata;
+
+/**
+ * A JAX-RS resource representing a {@link ProductPage}.
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+@XmlRootElement(name = "productPage")
+@XmlType(
+    propOrder = {
+      "pageSize",
+      "pageNum",
+      "totalPages",
+      "numOfHits",
+      "metadataResource",
+      "productResources"
+    })
+@XmlAccessorType(XmlAccessType.NONE)
+public class ProductPageResource {
+
+  private MetadataResource metadataResource;
+  private List<ProductResource> productResources = new ArrayList<ProductResource>();
+  private int pageSize;
+  private int pageNum;
+  private int totalPages;
+  private long numOfHits;
+
+  /* The file manager's working directory for this resource, used for example
+   when creating zip archives.
+  */
+  private File workingDir;
+
+  /** Default constructor required by JAXB. */
+  public ProductPageResource() {}
+
+  /**
+   * Constructor that sets the ProductPage, metadata and working directory for the ProductPage
+   * resource.
+   *
+   * @param page the productpage for the dataset
+   * @param productMetaDataList the metadata for the dataset
+   * @param productReferencesList the References for the dataset
+   * @param workingDir the working directory for creating temporary files to attach to responses
+   */
+  public ProductPageResource(
+      ProductPage page,
+      List<Metadata> productMetaDataList,
+      List<List<Reference>> productReferencesList,
+      File workingDir) {
+
+    this.pageSize = page.getPageSize();
+    this.pageNum = page.getPageNum();
+    this.totalPages = page.getTotalPages();
+    this.numOfHits = page.getNumOfHits();
+
+    this.workingDir = workingDir;
+
+    List<Product> pageProducts = page.getPageProducts();
+    for (int i = 0; i < pageProducts.size(); i++) {
+
+      Product product = pageProducts.get(i);
+      Metadata metadata = productMetaDataList.get(i);
+      List<Reference> references = productReferencesList.get(i);
+
+      this.productResources.add(
+          new ProductResource(product, metadata, productReferencesList.get(0), workingDir));
+    }
+  }
+
+  /**
+   * Adds a {@link ProductResource} to the list of product resources for the dataset.
+   *
+   * @param resource the resource to add to the dataset.
+   */
+  public void addProductResource(ProductResource resource) {
+    productResources.add(resource);
+  }
+
+  /**
+   * Gets the working directory for the dataset.
+   *
+   * @return the working directory
+   */
+  public File getWorkingDir() {
+    return workingDir;
+  }
+
+  @XmlElement(name = "pageSize")
+  public int getPageSize() {
+    return this.pageSize;
+  }
+
+  @XmlElement(name = "pageNum")
+  public int getPageNum() {
+    return pageNum;
+  }
+
+  @XmlElement(name = "totalPages")
+  public int getTotalPages() {
+    return totalPages;
+  }
+
+  @XmlElement(name = "numOfHits")
+  public long getNumOfHits() {
+    return numOfHits;
+  }
+
+  /**
+   * Gets the product resources for the dataset.
+   *
+   * @return the productResources
+   */
+  @XmlElementWrapper(name = "products")
+  @XmlElement(name = "product")
+  public List<ProductResource> getProductResources() {
+    return productResources;
+  }
+
+  /**
+   * Gets the metadata resource for the dataset.
+   *
+   * @return the metadata resource
+   */
+  @XmlElement(name = "metadata")
+  public MetadataResource getMetadataResource() {
+    return metadataResource;
+  }
+}
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/CasProductJaxrsService.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/CasProductJaxrsService.java
index ddb98de..031e9f5 100755
--- a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/CasProductJaxrsService.java
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/CasProductJaxrsService.java
@@ -13,10 +13,23 @@
  * 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.product.jaxrs.services;
 
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.ServletContext;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
 import org.apache.oodt.cas.filemgr.structs.FileTransferStatus;
 import org.apache.oodt.cas.filemgr.structs.Product;
 import org.apache.oodt.cas.filemgr.structs.ProductType;
@@ -24,6 +37,7 @@ import org.apache.oodt.cas.filemgr.structs.Reference;
 import org.apache.oodt.cas.filemgr.system.FileManagerClient;
 import org.apache.oodt.cas.metadata.Metadata;
 import org.apache.oodt.cas.product.exceptions.CasProductException;
+import org.apache.oodt.cas.product.jaxrs.enums.ErrorType;
 import org.apache.oodt.cas.product.jaxrs.exceptions.BadRequestException;
 import org.apache.oodt.cas.product.jaxrs.exceptions.NotFoundException;
 import org.apache.oodt.cas.product.jaxrs.resources.DatasetResource;
@@ -32,104 +46,88 @@ import org.apache.oodt.cas.product.jaxrs.resources.ReferenceResource;
 import org.apache.oodt.cas.product.jaxrs.resources.TransferResource;
 import org.apache.oodt.cas.product.jaxrs.resources.TransfersResource;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Vector;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.ServletContext;
-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;
-
 /**
- * Service class that handles HTTP requests and returns file manager entities
- * such as {@link Reference references} and {@link Product products} as
- * JAX-RS resources converted to different formats.
+ * Service class that handles HTTP requests and returns file manager entities such as {@link
+ * Reference references} and {@link Product products} as JAX-RS resources converted to different
+ * formats.
+ *
  * @author rlaidlaw
  * @version $Revision$
  */
-public class CasProductJaxrsService
-{
-  private static final Logger LOGGER = Logger.getLogger(CasProductJaxrsService
-    .class.getName());
+public class CasProductJaxrsService {
+  private static final Logger LOGGER = Logger.getLogger(CasProductJaxrsService.class.getName());
 
   // The servlet context, which is used to retrieve context parameters.
-  @Context
-  private ServletContext context;
-
-
+  @Context private ServletContext context;
 
   /**
-   * Gets an HTTP response that represents a {@link Reference} from a {@link
-   * Product} from the file manager.
+   * Gets an HTTP response that represents a {@link Reference} from a {@link Product} from the file
+   * manager.
+   *
    * @param productId the ID of the product that the reference belongs to
-   * @param refIndex the index of the reference within the product's list of
-   * references
-   * @return an HTTP response that represents a {@link Reference} from a {@link
-   * Product} from the file manager
+   * @param refIndex the index of the reference within the product's list of references
+   * @return an HTTP response that represents a {@link Reference} from a {@link Product} from the
+   *     file manager
    */
   @GET
   @Path("reference")
-  @Produces({"application/octet-stream", "application/xml", "application/json",
-    "application/atom+xml", "application/rdf+xml", "application/rss+xml",
-    "application/zip"})
+  @Produces({
+    "application/octet-stream",
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml",
+    "application/zip"
+  })
   public ReferenceResource getReference(
-    @QueryParam("productId") String productId,
-    @QueryParam("refIndex") int refIndex)
-  {
-    if (productId == null || productId.trim().equals(""))
-    {
-      throw new BadRequestException("This URL requires a productId query "
-        + "parameter with a product ID value, "
-        + "e.g. /reference?productId=1787a257-df87-11e2-8a2d-e3f6264e86c5");
+      @QueryParam("productId") String productId, @QueryParam("refIndex") int refIndex)
+      throws WebApplicationException {
+    if (productId == null || productId.trim().equals("")) {
+      throw new BadRequestException(
+          ErrorType.BAD_REQUEST_EXCEPTION_REFERENCE_RESOURCE.getErrorType());
     }
 
-    try
-    {
+    try {
       FileManagerClient client = getContextClient();
       Product product = client.getProductById(productId);
       List<Reference> references = client.getProductReferences(product);
 
-      return new ReferenceResource(productId, refIndex,
-        references.get(refIndex), getContextWorkingDir());
-    }
-    catch (Exception e)
-    {
+      return new ReferenceResource(
+          productId, refIndex, references.get(refIndex), getContextWorkingDir());
+    } catch (Exception e) {
+      // Just for Logging Purposes
       String message = "Unable to find the requested resource.";
       LOGGER.log(Level.FINE, message, e);
-      throw new NotFoundException(message + " " + e.getMessage());
+
+      throw new NotFoundException(e.getMessage());
     }
   }
 
-
-
   /**
-   * Gets an HTTP response that represents a {@link Product} from the file
-   * manager.
+   * Gets an HTTP response that represents a {@link Product} from the file manager.
+   *
    * @param productId the ID of the product
-   * @return an HTTP response that represents a {@link Product} from the file
-   * manager
+   * @return an HTTP response that represents a {@link Product} from the file manager
    */
   @GET
   @Path("product")
-  @Produces({"application/xml", "application/json", "application/atom+xml",
-    "application/rdf+xml", "application/rss+xml", "application/zip"})
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml",
+    "application/zip"
+  })
   public ProductResource getProduct(@QueryParam("productId") String productId)
-  {
-    if (productId == null || productId.trim().equals(""))
-    {
-      throw new BadRequestException("This URL requires a productId query "
-        + "parameter with a product ID value, "
-        + "e.g. /product?productId=1787a257-df87-11e2-8a2d-e3f6264e86c5");
+      throws WebApplicationException {
+    if (productId == null || productId.trim().equals("")) {
+      throw new BadRequestException(
+          ErrorType.BAD_REQUEST_EXCEPTION_PRODUCT_RESOURCE.getErrorType());
     }
 
-    try
-    {
+    try {
       FileManagerClient client = getContextClient();
 
       // Find the product.
@@ -138,43 +136,46 @@ public class CasProductJaxrsService
 
       // Create the product resource, add the product data and return the
       // resource as the HTTP response.
-      return new ProductResource(product, client.getMetadata(product),
-        product.getProductReferences(), getContextWorkingDir());
-    }
-    catch (Exception e)
-    {
+      return new ProductResource(
+          product,
+          client.getMetadata(product),
+          product.getProductReferences(),
+          getContextWorkingDir());
+    } catch (Exception e) {
+      // Just for Logging Purposes
       String message = "Unable to find the requested resource.";
       LOGGER.log(Level.FINE, message, e);
-      throw new NotFoundException(message + " " + e.getMessage());
+
+      throw new NotFoundException(e.getMessage());
     }
   }
 
-
-
   /**
-   * Gets an HTTP response that represents a set of {@link Product products}
-   * from the file manager.
-   * @param productTypeId the ID of the {@link ProductType} for the data set or
-   * "ALL" to denote all product types
-   * @return an HTTP response that represents a set of {@link Product products}
-   * from the file manager
+   * Gets an HTTP response that represents a set of {@link Product products} from the file manager.
+   *
+   * @param productTypeId the ID of the {@link ProductType} for the data set or "ALL" to denote all
+   *     product types
+   * @return an HTTP response that represents a set of {@link Product products} from the file
+   *     manager
    */
   @GET
   @Path("dataset")
-  @Produces({"application/xml", "application/json", "application/atom+xml",
-   "application/rdf+xml", "application/rss+xml", "application/zip"})
-  public DatasetResource getDataset(
-    @QueryParam("productTypeId") String productTypeId)
-  {
-    if (productTypeId == null || productTypeId.trim().equals(""))
-    {
-      throw new BadRequestException("This URL requires a productTypeId query "
-        + "parameter and either a product type ID value or 'ALL' for all "
-        + "product types.");
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml",
+    "application/zip"
+  })
+  public DatasetResource getDataset(@QueryParam("productTypeId") String productTypeId)
+      throws WebApplicationException {
+    if (productTypeId == null || productTypeId.trim().equals("")) {
+      throw new BadRequestException(
+          ErrorType.BAD_REQUEST_EXCEPTION_DATASET_RESOURCE.getErrorType());
     }
 
-    try
-    {
+    try {
       FileManagerClient client = getContextClient();
 
       String datasetId;
@@ -182,16 +183,13 @@ public class CasProductJaxrsService
       Metadata datasetMetadata;
 
       List<ProductType> productTypes = new Vector<ProductType>();
-      if (productTypeId.equals("ALL"))
-      {
+      if (productTypeId.equals("ALL")) {
         productTypes = client.getProductTypes();
         datasetId = productTypeId;
         datasetName = productTypeId;
         datasetMetadata = new Metadata();
         datasetMetadata.addMetadata("ProductType", productTypeId);
-      }
-      else
-      {
+      } else {
         ProductType productType = client.getProductTypeById(productTypeId);
         productTypes.add(productType);
         datasetId = productType.getProductTypeId();
@@ -199,170 +197,154 @@ public class CasProductJaxrsService
         datasetMetadata = productType.getTypeMetadata();
       }
 
-      String productDirPath = getContextWorkingDir().getCanonicalPath()
-        + "/" + datasetName;
+      String productDirPath = getContextWorkingDir().getCanonicalPath() + "/" + datasetName;
 
-      DatasetResource resource = new DatasetResource(datasetId, datasetName,
-        datasetMetadata, getContextWorkingDir());
+      DatasetResource resource =
+          new DatasetResource(datasetId, datasetName, datasetMetadata, getContextWorkingDir());
 
       // Add all products of the chosen type(s) to the dataset.
-      for (ProductType productType : productTypes)
-      {
-        for (Product product : client.getProductsByProductType(productType))
-        {
+      for (ProductType productType : productTypes) {
+        for (Product product : client.getProductsByProductType(productType)) {
           product.setProductReferences(client.getProductReferences(product));
-          resource.addProductResource(new ProductResource(product,
-            client.getMetadata(product), product.getProductReferences(),
-            new File(productDirPath)));
+          resource.addProductResource(
+              new ProductResource(
+                  product,
+                  client.getMetadata(product),
+                  product.getProductReferences(),
+                  new File(productDirPath)));
         }
       }
       return resource;
-    }
-    catch (Exception e)
-    {
+    } catch (Exception e) {
+      // Just for Logging Purposes
       String message = "Unable to find the requested resource.";
       LOGGER.log(Level.FINE, message, e);
-      throw new NotFoundException(message + " " + e.getMessage());
+
+      throw new NotFoundException(e.getMessage());
     }
   }
 
-
-
   /**
-   * Gets an HTTP response that represents the status of a currently active
-   * file transfer for the file manager.
+   * Gets an HTTP response that represents the status of a currently active file transfer for the
+   * file manager.
+   *
    * @param dataStoreRef the data store reference for the file being transferred
-   * @return an HTTP response that represents the status of a currently active
-   * file transfer for the file manager
+   * @return an HTTP response that represents the status of a currently active file transfer for the
+   *     file manager
    */
   @GET
   @Path("transfer")
-  @Produces({"application/xml", "application/json", "application/atom+xml",
-    "application/rdf+xml", "application/rss+xml"})
-  public TransferResource getTransfer(
-    @QueryParam("dataStoreRef") String dataStoreRef)
-  {
-    if (dataStoreRef == null || dataStoreRef.trim().equals(""))
-    {
-      throw new BadRequestException("This URL requires a dataStoreRef query "
-        + "parameter and a data store reference value, "
-        + "e.g. /transfer?dataStoreRef=file:/repository/test.txt/test.txt");
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml"
+  })
+  public TransferResource getTransfer(@QueryParam("dataStoreRef") String dataStoreRef)
+      throws WebApplicationException {
+    if (dataStoreRef == null || dataStoreRef.trim().equals("")) {
+      throw new BadRequestException(
+          ErrorType.BAD_REQUEST_EXCEPTION_TRANSFER_RESOURCE.getErrorType());
     }
 
-    try
-    {
+    try {
       FileManagerClient client = getContextClient();
-      for (FileTransferStatus status : client.getCurrentFileTransfers())
-      {
+      for (FileTransferStatus status : client.getCurrentFileTransfers()) {
         Reference reference = status.getFileRef();
-        if (dataStoreRef.equals(reference.getDataStoreReference()))
-        {
+        if (dataStoreRef.equals(reference.getDataStoreReference())) {
           Product product = status.getParentProduct();
           Metadata metadata = client.getMetadata(product);
           return new TransferResource(product, metadata, status);
         }
       }
 
-      throw new Exception("Unable to find a current file transfer status for"
-        + "data store reference: " + dataStoreRef);
-    }
-    catch (Exception e)
-    {
+      throw new NotFoundException(
+          ErrorType.NOT_FOUND_EXCEPTION_TRANSFER_RESOURCE.getErrorType() + dataStoreRef);
+    } catch (Exception e) {
+      // Just for Logging Purposes
       String message = "Unable to find the requested resource.";
       LOGGER.log(Level.FINE, message, e);
-      throw new NotFoundException(message + " " + e.getMessage());
+
+      throw new NotFoundException(e.getMessage());
     }
   }
 
-
-
   /**
-   * Gets an HTTP response that represents the statuses of all currently active
-   * file transfers for the file manager, optionally filtered by product ID.
+   * Gets an HTTP response that represents the statuses of all currently active file transfers for
+   * the file manager, optionally filtered by product ID.
+   *
    * @param productId the ID of a product or ALL to denote all products
-   * @return an HTTP response that represents the statuses of all currently
-   * active file transfers for the file manager
+   * @return an HTTP response that represents the statuses of all currently active file transfers
+   *     for the file manager
    */
   @GET
   @Path("transfers")
-  @Produces({"application/xml", "application/json", "application/atom+xml",
-    "application/rdf+xml", "application/rss+xml"})
-  public TransfersResource getTransfers(
-    @QueryParam("productId") String productId)
-  {
-    if (productId == null || productId.trim().equals(""))
-    {
-      throw new BadRequestException("This URL requires a productId query "
-        + "parameter and either a valid product ID value or 'ALL' for all "
-        + "products.");
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml"
+  })
+  public TransfersResource getTransfers(@QueryParam("productId") String productId)
+      throws WebApplicationException {
+    if (productId == null || productId.trim().equals("")) {
+      throw new BadRequestException(
+          ErrorType.BAD_REQUEST_EXCEPTION_DATASET_RESOURCE.getErrorType());
     }
 
-    try
-    {
-      List<TransferResource> transferResources =
-        new ArrayList<TransferResource>();
+    try {
+      List<TransferResource> transferResources = new ArrayList<TransferResource>();
       FileManagerClient client = getContextClient();
-      for (FileTransferStatus status : client.getCurrentFileTransfers())
-      {
+      for (FileTransferStatus status : client.getCurrentFileTransfers()) {
         Product product = status.getParentProduct();
-        if(productId.equals("ALL") || productId.equals(product.getProductId()))
-        {
+        if (productId.equals("ALL") || productId.equals(product.getProductId())) {
           Metadata metadata = client.getMetadata(product);
-          transferResources.add(
-            new TransferResource(product, metadata, status));
+          transferResources.add(new TransferResource(product, metadata, status));
         }
       }
       return new TransfersResource(productId, transferResources);
-    }
-    catch (Exception e)
-    {
+    } catch (Exception e) {
+      // Just for Logging Purposes
       String message = "Unable to find the requested resource.";
       LOGGER.log(Level.FINE, message, e);
-      throw new NotFoundException(message + " " + e.getMessage());
+
+      throw new NotFoundException(e.getMessage());
     }
   }
 
-
-
   /**
    * Gets the file manager's working directory from the servlet context.
+   *
    * @return the file manager working directory
-   * @throws Exception if an object cannot be retrieved from the context
-   * attribute
+   * @throws Exception if an object cannot be retrieved from the context attribute
    */
   public File getContextWorkingDir() throws CasProductException {
     Object workingDirObject = context.getAttribute("workingDir");
-    if (workingDirObject != null && workingDirObject instanceof File)
-    {
+    if (workingDirObject != null && workingDirObject instanceof File) {
       return (File) workingDirObject;
     }
 
-    String message = "Unable to get the file manager's working "
-      + "directory from the servlet context.";
+    String message = ErrorType.CAS_PRODUCT_EXCEPTION_FILEMGR_WORKING_DIR_UNAVILABLE.getErrorType();
     LOGGER.log(Level.WARNING, message);
     throw new CasProductException(message);
   }
 
-
-
   /**
    * Gets the file manager client instance from the servlet context.
+   *
    * @return the file manager client instance from the servlet context attribute
-   * @throws Exception if an object cannot be retrieved from the context
-   * attribute
+   * @throws Exception if an object cannot be retrieved from the context attribute
    */
-  public FileManagerClient getContextClient()
-      throws CasProductException {
+  public FileManagerClient getContextClient() throws CasProductException {
     // Get the file manager client from the servlet context.
     Object clientObject = context.getAttribute("client");
-    if (clientObject != null &&
-        clientObject instanceof FileManagerClient)
-    {
+    if (clientObject != null && clientObject instanceof FileManagerClient) {
       return (FileManagerClient) clientObject;
     }
 
-    String message = "Unable to get the file manager client from the "
-      + "servlet context.";
+    String message = ErrorType.CAS_PRODUCT_EXCEPTION_FILEMGR_CLIENT_UNAVILABLE.getErrorType();
     LOGGER.log(Level.WARNING, message);
     throw new CasProductException(message);
   }
diff --git a/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/FileManagerJaxrsServiceV2.java b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/FileManagerJaxrsServiceV2.java
new file mode 100644
index 0000000..c4f48bd
--- /dev/null
+++ b/webapp/fmprod/src/main/java/org/apache/oodt/cas/product/jaxrs/services/FileManagerJaxrsServiceV2.java
@@ -0,0 +1,434 @@
+/*
+ * 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.product.jaxrs.services;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import javax.activation.DataHandler;
+import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+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.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.oodt.cas.filemgr.ingest.StdIngester;
+import org.apache.oodt.cas.filemgr.metadata.CoreMetKeys;
+import org.apache.oodt.cas.filemgr.structs.Product;
+import org.apache.oodt.cas.filemgr.structs.ProductPage;
+import org.apache.oodt.cas.filemgr.structs.Reference;
+import org.apache.oodt.cas.filemgr.structs.exceptions.CatalogException;
+import org.apache.oodt.cas.filemgr.system.FileManagerClient;
+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.extractors.MetReaderExtractor;
+import org.apache.oodt.cas.product.exceptions.CasProductException;
+import org.apache.oodt.cas.product.jaxrs.enums.ErrorType;
+import org.apache.oodt.cas.product.jaxrs.exceptions.BadRequestException;
+import org.apache.oodt.cas.product.jaxrs.exceptions.InternalServerErrorException;
+import org.apache.oodt.cas.product.jaxrs.exceptions.NotFoundException;
+import org.apache.oodt.cas.product.jaxrs.filters.CORSFilter;
+import org.apache.oodt.cas.product.jaxrs.resources.FMStatusResource;
+import org.apache.oodt.cas.product.jaxrs.resources.ProductPageResource;
+import org.apache.oodt.cas.product.jaxrs.resources.ProductResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Service class for Proposing Apache OODT-2.0 FileManager REST-APIs This handles HTTP requests and
+ * returns file manager entities JAX-RS resources converted to different formats.
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+public class FileManagerJaxrsServiceV2 {
+
+  private static Logger logger = LoggerFactory.getLogger(FileManagerJaxrsServiceV2.class);
+
+  /* The servlet context, which is used to retrieve context parameters. */
+  @Context private ServletContext context;
+
+  /**
+   * Gets an HTTP request that represents a {@link ProductPage} from the file manager.
+   *
+   * @param productTypeName the Name of a productType
+   * @return an HTTP response that represents a {@link ProductPage} from the file manager
+   */
+  @GET
+  @Path("products")
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml"
+  })
+  public ProductPageResource getFirstPage(@QueryParam("productTypeName") String productTypeName)
+      throws WebApplicationException {
+
+    try {
+      FileManagerClient client = getContextClient();
+
+      /* Get the first ProductPage */
+      ProductPage genericFile = client.getFirstPage(client.getProductTypeByName(productTypeName));
+
+      return getProductPageResource(client, genericFile);
+
+    } catch (Exception e) {
+      throw new NotFoundException(e.getMessage());
+    }
+  }
+
+  /**
+   * Gets an HTTP request that represents a {@link ProductPage} from the file manager.
+   *
+   * @param productTypeName the Name of a productType
+   * @param currentProductPage the current productPage
+   * @return an HTTP response that represents a {@link ProductPage} from the file manager
+   */
+  @GET
+  @Path("products")
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml"
+  })
+  public ProductPageResource getNextPage(
+      @QueryParam("productTypeName") String productTypeName,
+      @QueryParam("currentProductPage") int currentProductPage)
+      throws WebApplicationException {
+
+    try {
+      FileManagerClient client = getContextClient();
+
+      /* Get the first ProductPage */
+      ProductPage firstpage = client.getFirstPage(client.getProductTypeByName(productTypeName));
+
+      /* Get the next ProductPage */
+      ProductPage nextPage =
+          client.getNextPage(client.getProductTypeByName(productTypeName), firstpage);
+
+      /* Searching for the current page */
+      while (nextPage.getPageNum() != currentProductPage - 1) {
+        nextPage = client.getNextPage(client.getProductTypeByName(productTypeName), nextPage);
+      }
+
+      /* Get the next page from the current page */
+      ProductPage genericFile =
+          client.getNextPage(client.getProductTypeByName(productTypeName), nextPage);
+
+      /* Return ProductPage resource */
+      return getProductPageResource(client, genericFile);
+
+    } catch (Exception e) {
+      throw new NotFoundException(e.getMessage());
+    }
+  }
+
+  /**
+   * This method is for creating a ProductPageResource Response and return it This method is for
+   * creating a ProductPageResource {@link ProductPage} Response and return it
+   *
+   * @param client FileManager client
+   * @param genericFile First/next/prev ProductPage
+   */
+  private ProductPageResource getProductPageResource(
+      FileManagerClient client, ProductPage genericFile)
+      throws CatalogException, CasProductException {
+
+    /* List for storing Metadata of the products in the ProductPage */
+    List<Metadata> proMetaDataList = new ArrayList<>();
+
+    /* List for storing References of the products in the ProductPage */
+    List<List<Reference>> proReferencesList = new ArrayList<>();
+
+    for (Product pro : genericFile.getPageProducts()) {
+      Metadata metadata = client.getMetadata(pro);
+      List<Reference> productReferences = pro.getProductReferences();
+      proMetaDataList.add(metadata);
+      proReferencesList.add(productReferences);
+    }
+
+    return new ProductPageResource(
+        genericFile, proMetaDataList, proReferencesList, getContextWorkingDir());
+  }
+
+  /**
+   * Gets the file manager's working directory from the servlet context.
+   *
+   * @return the file manager working directory
+   * @throws Exception if an object cannot be retrieved from the context attribute
+   */
+  public File getContextWorkingDir() throws CasProductException {
+    Object workingDirObject = context.getAttribute("workingDir");
+    if (workingDirObject != null && workingDirObject instanceof File) {
+      return (File) workingDirObject;
+    }
+
+    String message = ErrorType.CAS_PRODUCT_EXCEPTION_FILEMGR_WORKING_DIR_UNAVILABLE.getErrorType();
+    logger.debug("File Manager Exception : ", message);
+    throw new CasProductException(message);
+  }
+
+  /**
+   * Gets the file manager client instance from the servlet context.
+   *
+   * @return the file manager client instance from the servlet context attribute
+   * @throws Exception if an object cannot be retrieved from the context attribute
+   */
+  public FileManagerClient getContextClient() throws CasProductException {
+    /* Get the file manager client from the servlet context. */
+    Object clientObject = context.getAttribute("client");
+    if (clientObject != null && clientObject instanceof FileManagerClient) {
+      return (FileManagerClient) clientObject;
+    }
+
+    String message = ErrorType.CAS_PRODUCT_EXCEPTION_FILEMGR_CLIENT_UNAVILABLE.getErrorType();
+    logger.debug("File Manager Exception: ", message);
+    throw new CasProductException(message);
+  }
+
+  /**
+   * Gets an HTTP response that represents a {@link Product} from the file manager.
+   *
+   * @param productId the ID of the product
+   * @return an HTTP response that represents a {@link Product} from the file manager
+   */
+  @GET
+  @Path("product")
+  @Produces({
+    "application/xml",
+    "application/json",
+    "application/atom+xml",
+    "application/rdf+xml",
+    "application/rss+xml",
+    "application/zip"
+  })
+  public ProductResource getProduct(@QueryParam("productId") String productId)
+      throws WebApplicationException {
+    if (productId == null || productId.trim().equals("")) {
+      throw new BadRequestException(
+          ErrorType.BAD_REQUEST_EXCEPTION_PRODUCT_RESOURCE.getErrorType());
+    }
+
+    try {
+      FileManagerClient client = getContextClient();
+
+      /* Find the product. */
+      Product product = client.getProductById(productId);
+      product.setProductReferences(client.getProductReferences(product));
+
+      /*
+       Create the product resource, add the product data and return the
+       resource as the HTTP response.
+      */
+      return new ProductResource(
+          product,
+          client.getMetadata(product),
+          product.getProductReferences(),
+          getContextWorkingDir());
+    } catch (Exception e) {
+      throw new NotFoundException(e.getMessage());
+    }
+  }
+
+  /**
+   * Gets an HTTP response that represents a {@link Product} from the file manager.
+   *
+   * @param productFile the Product File to ingest
+   * @param productType ProductType of the ingesting Product - eg.GenericFile
+   * @param productStructure - Product Structure of the ingesting product - eg. Flat for
+   *     Files/Hierarchy for Directory
+   * @return an HTTP response that represents the Ingesting Id if success
+   */
+  @POST
+  @Path("productWithFile")
+  @Produces({"application/json", "application/xml"})
+  @Consumes({MediaType.MULTIPART_FORM_DATA})
+  public Response ingestProduct(
+      @Multipart("productFile") Attachment productFile,
+      @QueryParam("productType") String productType,
+      @QueryParam("productStructure") String productStructure) {
+    try {
+      String transferServiceFacClass =
+          "org.apache.oodt.cas." + "filemgr.datatransfer.LocalDataTransferFactory";
+
+      /* Take Data Handlers for Product and Metadata Files */
+      DataHandler productFileDataHandler = productFile.getDataHandler();
+
+      /* Get the input Streams of the CXF Attachments */
+      InputStream productFileInputStream = productFileDataHandler.getInputStream();
+
+      /* Write the Product File and MetaFiles to a temporary Files in server before ingest. */
+      File inputProductFile =
+          writeToFileServer(
+              productFileInputStream, productFile.getContentDisposition().getParameter("filename"));
+
+      /* Get File Manager and Its URL */
+      FileManagerClient client = getContextClient();
+      URL fmURL = client.getFileManagerUrl();
+
+      /* Use StdIngester for Simple File Ingesting */
+      StdIngester ingester = new StdIngester(transferServiceFacClass);
+
+      /*
+       * Use MetaReaderExtracter to extract File Metadata from Product File
+       *  * A Met Extractor that assumes that the .met file has already been generated.
+       */
+      MetExtractor metExtractor = new MetReaderExtractor();
+      Metadata prodMeta = metExtractor.extractMetadata(inputProductFile);
+
+      /* Add Several Metadata to Metadata File */
+      prodMeta.addMetadata(CoreMetKeys.FILENAME, inputProductFile.getName());
+      prodMeta.addMetadata(CoreMetKeys.PRODUCT_TYPE, productType);
+      prodMeta.addMetadata(CoreMetKeys.PRODUCT_STRUCTURE, productStructure);
+      prodMeta.addMetadata(CoreMetKeys.PRODUCT_NAME, inputProductFile.getName());
+
+      /* Product File Location. should Only provide File Path without FileName */
+      prodMeta.addMetadata(
+          CoreMetKeys.FILE_LOCATION,
+          (inputProductFile
+              .getAbsolutePath()
+              .substring(0, inputProductFile.getAbsolutePath().lastIndexOf("/"))));
+
+      String ingest = ingester.ingest(fmURL, inputProductFile, prodMeta);
+      return Response.ok(ingest).build();
+    } catch (Exception e) {
+      throw new InternalServerErrorException(e.getMessage());
+    }
+  }
+
+  /**
+   * Gets an HTTP response that represents a {@link Product} from the file manager.
+   *
+   * @param productFile the Product File to ingest
+   * @param metadataFile the Metadata File to ingest
+   * @return an HTTP response that represents the Ingesting Id if success
+   */
+  @POST
+  @Path("productWithMeta")
+  @Produces({"application/json", "application/xml"})
+  @Consumes(MediaType.MULTIPART_FORM_DATA)
+  public Response ingestProduct(
+      @Multipart("productFile") Attachment productFile,
+      @Multipart("metadataFile") Attachment metadataFile) {
+    try {
+      String transferServiceFacClass =
+          "org.apache.oodt.cas." + "filemgr.datatransfer.LocalDataTransferFactory";
+
+      /* Take Data Handlers for Product and Metadata Files */
+      DataHandler productFileDataHandler = productFile.getDataHandler();
+      DataHandler metadataFileDataHandler = metadataFile.getDataHandler();
+
+      /* Get the input Streams of the CXF Attachments */
+      InputStream productFileInputStream = productFileDataHandler.getInputStream();
+      InputStream metadataFileInputStream = metadataFileDataHandler.getInputStream();
+
+      /* Write the Product File and MetaFiles to a temporary Files in server before ingest. */
+      File inputProductFile =
+          writeToFileServer(
+              productFileInputStream, productFile.getContentDisposition().getParameter("filename"));
+
+      //Get File Manager and Its URL
+      FileManagerClient client = getContextClient();
+      URL fmURL = client.getFileManagerUrl();
+
+      /* Use StdIngester for Simple File Ingesting */
+      StdIngester ingester = new StdIngester(transferServiceFacClass);
+
+      Metadata prodMeta = new SerializableMetadata(metadataFileInputStream);
+
+      /* Add Several Metadata to Metadata File */
+      prodMeta.addMetadata(CoreMetKeys.FILENAME, inputProductFile.getName());
+      prodMeta.addMetadata(CoreMetKeys.PRODUCT_NAME, inputProductFile.getName());
+
+      /* Product File Location. should Only provide File Path without FileName */
+      prodMeta.addMetadata(
+          CoreMetKeys.FILE_LOCATION,
+          (inputProductFile
+              .getAbsolutePath()
+              .substring(0, inputProductFile.getAbsolutePath().lastIndexOf("/"))));
+
+      String ingest = ingester.ingest(fmURL, inputProductFile, prodMeta);
+      return Response.ok(ingest).build();
+    } catch (Exception e) {
+      throw new InternalServerErrorException(e.getMessage());
+    }
+  }
+
+  /**
+   * This method uses to Write an InputStream to File in the Server
+   *
+   * @param inputStream
+   * @param fileName
+   */
+  private File writeToFileServer(InputStream inputStream, String fileName) {
+
+    OutputStream outputStream = null;
+    File file = new File(fileName);
+    try {
+      outputStream = new FileOutputStream(file);
+      int read = 0;
+      byte[] bytes = new byte[1024];
+      while ((read = inputStream.read(bytes)) != -1) {
+        outputStream.write(bytes, 0, read);
+      }
+      outputStream.flush();
+      outputStream.close();
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } finally {
+      return file;
+    }
+  }
+
+  /**
+   * This method is for getting the current status of FileManager component
+   *
+   * @return Response object with status and FMProb URL
+   */
+  @GET
+  @Path("fmprodstatus")
+  @Produces({"application/json", "application/xml"})
+  public Response getFmProductStatus() {
+    try {
+      FileManagerClient client = getContextClient();
+      String URL = client.getFileManagerUrl().toString();
+      boolean fmStatus = client.isAlive();
+      FMStatusResource status = new FMStatusResource(URL, fmStatus);
+      return Response.ok(status).build();
+    } catch (Exception e) {
+      throw new InternalServerErrorException(e.getMessage());
+    }
+  }
+}
diff --git a/webapp/fmprod/src/main/webapp/WEB-INF/web.xml b/webapp/fmprod/src/main/webapp/WEB-INF/web.xml
index 155fb0d..943a930 100644
--- a/webapp/fmprod/src/main/webapp/WEB-INF/web.xml
+++ b/webapp/fmprod/src/main/webapp/WEB-INF/web.xml
@@ -72,7 +72,7 @@
     <init-param>
       <param-name>jaxrs.serviceClasses</param-name>
       <param-value>
-        org.apache.oodt.cas.product.jaxrs.services.CasProductJaxrsService
+        org.apache.oodt.cas.product.jaxrs.services.FileManagerJaxrsServiceV2
       </param-value>
     </init-param>
     <init-param>
@@ -87,7 +87,11 @@
         org.apache.oodt.cas.product.jaxrs.writers.DatasetZipWriter,
         org.apache.oodt.cas.product.jaxrs.writers.DatasetRdfWriter,
         org.apache.oodt.cas.product.jaxrs.writers.DatasetRssWriter,
-        org.apache.oodt.cas.product.jaxrs.writers.TransfersRssWriter
+        org.apache.oodt.cas.product.jaxrs.writers.TransfersRssWriter,
+        org.apache.oodt.cas.product.jaxrs.exceptionmappers.NotFoundExceptionMapper,
+        org.apache.oodt.cas.product.jaxrs.exceptionmappers.BadRequestExceptionMapper,
+        org.apache.oodt.cas.product.jaxrs.exceptionmappers.InternalServerErrorExceptionMapper,
+        org.apache.oodt.cas.product.jaxrs.exceptionmappers.CasProductExceptionMapper,
       </param-value>
     </init-param>
     <init-param>
@@ -113,7 +117,6 @@
     </init-param>
   </servlet>
 
-
   <servlet-mapping>
     <servlet-name>RSSServlet</servlet-name>
     <url-pattern>/viewRecent</url-pattern>
@@ -148,4 +151,17 @@
     <servlet-name>CasProductJaxrsServlet</servlet-name>
     <url-pattern>/jaxrs/*</url-pattern>
   </servlet-mapping>
+
+  <!-- CORS Header Filtering -->
+  <filter>
+    <filter-name>CorsFilter</filter-name>
+    <filter-class>org.apache.oodt.cas.product.jaxrs.filters.CORSFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>CorsFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+
 </web-app>
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/DatasetResourceTest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/DatasetResourceTest.java
index 6101f62..530e51e 100644
--- a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/DatasetResourceTest.java
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/DatasetResourceTest.java
@@ -23,13 +23,11 @@ import java.io.File;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
-
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
-
 import org.apache.oodt.cas.filemgr.structs.Product;
 import org.apache.oodt.cas.filemgr.structs.ProductType;
 import org.apache.oodt.cas.filemgr.structs.Reference;
@@ -70,7 +68,7 @@ public class DatasetResourceTest
     List<Reference> references1 = new ArrayList<Reference>();
     references1.add(reference1);
 
-    Hashtable metadataEntries1 = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries1 = new HashMap<>();
     metadataEntries1.put("product1_meta", "test1");
     Metadata metadata1 = new Metadata();
     metadata1.addMetadata(metadataEntries1);
@@ -91,7 +89,7 @@ public class DatasetResourceTest
     List<Reference> references2 = new ArrayList<Reference>();
     references2.add(reference2);
 
-    Hashtable metadataEntries2 = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries2 = new HashMap<>();
     metadataEntries2.put("product2_meta", "test2");
     Metadata metadata2 = new Metadata();
     metadata2.addMetadata(metadataEntries2);
@@ -106,7 +104,7 @@ public class DatasetResourceTest
 
     // Create a DatasetResource using ProductType, Metadata and ProductResource
     // instances.
-    Hashtable metadataEntries3 = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries3 = new HashMap<>();
     metadataEntries3.put("dataset_meta", "test3");
     Metadata metadata3 = new Metadata();
     metadata3.addMetadata(metadataEntries3);
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/MetadataResourceTest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/MetadataResourceTest.java
index 853bb3f..ffd15c4 100644
--- a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/MetadataResourceTest.java
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/MetadataResourceTest.java
@@ -22,13 +22,11 @@ import static org.junit.Assert.assertTrue;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
-
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
-
 import org.apache.oodt.cas.metadata.Metadata;
 import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
@@ -65,7 +63,7 @@ public class MetadataResourceTest
       + "</metadata>";
 
     // Create a MetadataResource using a Metadata instance.
-    Hashtable metadataEntries = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries = new HashMap<>();
     metadataEntries.put("1", "one");
     metadataEntries.put("2", "two");
     metadataEntries.put("3", "three");
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductPageResourceTest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductPageResourceTest.java
new file mode 100644
index 0000000..9fe4642
--- /dev/null
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductPageResourceTest.java
@@ -0,0 +1,158 @@
+package org.apache.oodt.cas.product.jaxrs.resources;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+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.Reference;
+import org.apache.oodt.cas.metadata.Metadata;
+import org.apache.tika.mime.MimeTypeException;
+import org.apache.tika.mime.MimeTypes;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+/**
+ * Implements tests for methods in the {@link ProductPageResource} class.
+ *
+ * @author ngimhana (Nadeeshan Gimhana)
+ */
+public class ProductPageResourceTest {
+
+  @Test
+  public void testXmlMarshalling()
+      throws JAXBException, IOException, SAXException, MimeTypeException {
+
+    /*
+     Create a ProductResource using ProductType, Reference, Metadata and
+     Product instances.
+    */
+    HashMap<String, Object> metadataEntries = new HashMap<>();
+    metadataEntries.put("CAS.Test", "test value");
+    Metadata metadata = new Metadata();
+    metadata.addMetadata(metadataEntries);
+
+    List<Metadata> metadataList = new Vector<>();
+    metadataList.add(metadata);
+
+    Reference reference =
+        new Reference("original", "dataStore", 1000, new MimeTypes().forName("text/plain"));
+    List<Reference> references = new ArrayList<>();
+    references.add(reference);
+
+    List<List<Reference>> productReferencesList = new Vector<>();
+    productReferencesList.add(references);
+
+    ProductType productType =
+        new ProductType("1", "GenericFile", "test type", "repository", "versioner");
+
+    Product product = new Product();
+    product.setProductId("123");
+    product.setProductName("test.txt");
+    product.setProductStructure(Product.STRUCTURE_FLAT);
+    product.setProductType(productType);
+    product.setTransferStatus("RECEIVED");
+
+    List<Product> pageProducts = new Vector<>();
+    pageProducts.add(product);
+
+    ProductPage productPage = new ProductPage(1, 1, 20, pageProducts);
+
+    /** Create a ProductPageResource using Reference, Metadata and Product instances. * */
+    ProductPageResource resource =
+        new ProductPageResource(productPage, metadataList, productReferencesList, new File("/tmp"));
+
+    /** Generate the expected output. * */
+    String expectedXml =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+            + "<productPage>"
+            + "<pageSize>"
+            + resource.getPageSize()
+            + "</pageSize>"
+            + "<pageNum>"
+            + resource.getPageNum()
+            + "</pageNum>"
+            + "<totalPages>"
+            + resource.getTotalPages()
+            + "</totalPages>"
+            + "<numOfHits>"
+            + resource.getNumOfHits()
+            + "</numOfHits>"
+            + "<products>"
+            + "<product>"
+            + "<id>"
+            + product.getProductId()
+            + "</id>"
+            + "<name>"
+            + product.getProductName()
+            + "</name>"
+            + "<structure>"
+            + product.getProductStructure()
+            + "</structure>"
+            + "<type>"
+            + productType.getName()
+            + "</type>"
+            + "<transferStatus>"
+            + product.getTransferStatus()
+            + "</transferStatus>"
+            + "<metadata>"
+            + "<keyval>"
+            + "<key>"
+            + metadataList.get(0).getAllKeys().get(0)
+            + "</key>"
+            + "<val>"
+            + metadataList.get(0).getAllValues().get(0)
+            + "</val>"
+            + "</keyval>"
+            + "</metadata>"
+            + "<references>"
+            + "<reference>"
+            + "<productId>"
+            + product.getProductId()
+            + "</productId>"
+            + "<refIndex>0</refIndex>"
+            + "<dataStoreReference>"
+            + productReferencesList.get(0).get(0).getDataStoreReference()
+            + "</dataStoreReference>"
+            + "<originalReference>"
+            + productReferencesList.get(0).get(0).getOrigReference()
+            + "</originalReference>"
+            + "<mimeType>"
+            + productReferencesList.get(0).get(0).getMimeType().getName()
+            + "</mimeType>"
+            + "<fileSize>"
+            + productReferencesList.get(0).get(0).getFileSize()
+            + "</fileSize>"
+            + "</reference>"
+            + "</references>"
+            + "</product>"
+            + "</products>"
+            + "</productPage>";
+
+    /** Set up a JAXB context and marshall the ProductResource to XML. * */
+    JAXBContext context = JAXBContext.newInstance(resource.getClass());
+    Marshaller marshaller = context.createMarshaller();
+    StringWriter writer = new StringWriter();
+    marshaller.marshal(resource, writer);
+
+    /** Compare the expected and actual outputs. * */
+    XMLUnit.setIgnoreWhitespace(true);
+    XMLUnit.setIgnoreComments(true);
+    XMLUnit.setIgnoreAttributeOrder(true);
+    Diff diff = new Diff(expectedXml, writer.toString());
+    assertTrue(
+        "The output XML was different to the expected XML: " + diff.toString(), diff.identical());
+  }
+}
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductResourceTest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductResourceTest.java
index 6cf9c12..a6a6bbf 100644
--- a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductResourceTest.java
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/ProductResourceTest.java
@@ -23,13 +23,11 @@ import java.io.File;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
-
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
-
 import org.apache.oodt.cas.filemgr.structs.Product;
 import org.apache.oodt.cas.filemgr.structs.ProductType;
 import org.apache.oodt.cas.filemgr.structs.Reference;
@@ -62,7 +60,7 @@ public class ProductResourceTest
   {
     // Create a ProductResource using ProductType, Reference, Metadata and
     // Product instances.
-    Hashtable metadataEntries = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries = new HashMap<>();
     metadataEntries.put("CAS.Test", "test value");
     Metadata metadata = new Metadata();
     metadata.addMetadata(metadataEntries);
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransferResourceTest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransferResourceTest.java
index 16e89ad..25d0697 100644
--- a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransferResourceTest.java
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransferResourceTest.java
@@ -21,12 +21,10 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.io.StringWriter;
-import java.util.Hashtable;
-
+import java.util.HashMap;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
-
 import org.apache.oodt.cas.filemgr.structs.FileTransferStatus;
 import org.apache.oodt.cas.filemgr.structs.Product;
 import org.apache.oodt.cas.filemgr.structs.ProductType;
@@ -60,7 +58,7 @@ public class TransferResourceTest
   {
     // Create a TransferResource using ProductType, Product, Metadata, Reference
     // and FileTransferStatus instances.
-    Hashtable metadataEntries = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries = new HashMap<>();
     metadataEntries.put("CAS.ProductReceivedTime", "2013-09-12T16:25:50.662Z");
     Metadata metadata = new Metadata();
     metadata.addMetadata(metadataEntries);
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransfersResourceTest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransfersResourceTest.java
index e490bc6..bb79984 100644
--- a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransfersResourceTest.java
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs/resources/TransfersResourceTest.java
@@ -22,13 +22,11 @@ import static org.junit.Assert.assertTrue;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
-
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
-
 import org.apache.oodt.cas.filemgr.structs.FileTransferStatus;
 import org.apache.oodt.cas.filemgr.structs.Product;
 import org.apache.oodt.cas.filemgr.structs.ProductType;
@@ -62,7 +60,7 @@ public class TransfersResourceTest
   {
     // Create a FileTransferStatus instance using Metadata, Reference,
     // ProductType and Product instances.
-    Hashtable metadataEntries1 = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries1 = new HashMap<>();
     metadataEntries1.put("CAS.ProductReceivedTime", "2013-09-12T16:25:50.662Z");
     Metadata metadata1 = new Metadata();
     metadata1.addMetadata(metadataEntries1);
@@ -85,7 +83,7 @@ public class TransfersResourceTest
 
     // Create another FileTransferStatus instance using Metadata, Reference,
     // ProductType and Product instances.
-    Hashtable metadataEntries2 = new Hashtable<String, Object>();
+    HashMap<String, Object> metadataEntries2 = new HashMap<>();
     metadataEntries2.put("CAS.ProductReceivedTime", "2011-04-11T11:59:59.662Z");
     Metadata metadata2 = new Metadata();
     metadata2.addMetadata(metadataEntries2);
@@ -108,7 +106,7 @@ public class TransfersResourceTest
 
     // Create a TransfersResource using the two FileTransferStatus instances to
     // generate TransferResource instances for the TransfersResource.
-    List<TransferResource> resources = new ArrayList<TransferResource>();
+    List<TransferResource> resources = new ArrayList<>();
     resources.add(new TransferResource(product1, metadata1, status1));
     resources.add(new TransferResource(product2, metadata2, status2));
     TransfersResource resource = new TransfersResource("ALL", resources);
diff --git a/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs_rest/RestAPITest.java b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs_rest/RestAPITest.java
new file mode 100644
index 0000000..c2870c9
--- /dev/null
+++ b/webapp/fmprod/src/test/java/org/apache/oodt/cas/product/jaxrs_rest/RestAPITest.java
@@ -0,0 +1,45 @@
+package org.apache.oodt.cas.product.jaxrs_rest;
+
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.oodt.cas.product.jaxrs.resources.ProductResource;
+import org.apache.oodt.cas.product.jaxrs.services.CasProductJaxrsService;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class RestAPITest extends Assert {
+//    private final static String ENDPOINT_ADDRESS = "http://localhost:8080/cas_product_war/jaxrs/product?productId=" +"";
+//    private static Server server;
+//
+//    @BeforeClass
+//    public static void initialize() throws Exception {
+//        startServer();
+//    }
+//
+//    private static void startServer() throws Exception {
+//        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+//        sf.setResourceProvider(CasProductJaxrsService.class,
+//        new SingletonResourceProvider(new CasProductJaxrsService(), true));
+//        sf.setResourceClasses(CasProductJaxrsService.class);
+//        sf.setAddress(ENDPOINT_ADDRESS);
+//        server = sf.create();
+//    }
+//
+//    @AfterClass
+//    public static void destroy() {
+//        server.stop();
+//        server.destroy();
+//    }
+//
+//    @Test
+//    public void testGetProductResourceWithWebClient() {
+//        WebClient client = WebClient.create(ENDPOINT_ADDRESS);
+//        ProductResource productResource = client.get(ProductResource.class);
+//        assertEquals(0, productResource.getProductId());
+//
+//    }
+}