You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sqoop.apache.org by bl...@apache.org on 2012/09/21 22:05:31 UTC

[2/2] SQOOP-608 Implement job resource from end to end

http://git-wip-us.apache.org/repos/asf/sqoop/blob/866d46df/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java b/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java
new file mode 100644
index 0000000..6fbf47c
--- /dev/null
+++ b/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java
@@ -0,0 +1,212 @@
+/**
+ * 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.sqoop.handler;
+
+import org.apache.log4j.Logger;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.connector.ConnectorManager;
+import org.apache.sqoop.framework.FrameworkManager;
+import org.apache.sqoop.json.JobBean;
+import org.apache.sqoop.json.JsonBean;
+import org.apache.sqoop.json.ValidationBean;
+import org.apache.sqoop.model.MConnection;
+import org.apache.sqoop.model.MJob;
+import org.apache.sqoop.model.MJobForms;
+import org.apache.sqoop.repository.Repository;
+import org.apache.sqoop.repository.RepositoryManager;
+import org.apache.sqoop.server.RequestContext;
+import org.apache.sqoop.server.RequestHandler;
+import org.apache.sqoop.server.common.ServerError;
+import org.apache.sqoop.validation.Status;
+import org.apache.sqoop.validation.Validator;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Job request handler is supporting following resources:
+ *
+ * GET /v1/job
+ * Get brief list of all jobs present in the system.
+ *
+ * GET /v1/job/:jid
+ * Return details about one particular job with id :jid or about all of
+ * them if :jid equals to "all".
+ *
+ * POST /v1/job
+ * Create new job
+ *
+ * PUT /v1/job/:jid
+ * Update job with id :jid.
+ *
+ * DELETE /v1/job/:jid
+ * Remove job with id :jid
+ */
+public class JobRequestHandler implements RequestHandler {
+
+  private static final Logger LOG =
+      Logger.getLogger(ConnectorRequestHandler.class);
+
+  public JobRequestHandler() {
+    LOG.info("JobRequestHandler initialized");
+  }
+
+  @Override
+  public JsonBean handleEvent(RequestContext ctx) throws SqoopException {
+    switch (ctx.getMethod()) {
+      case GET:
+        return getJobs(ctx);
+      case POST:
+        return createUpdateJob(ctx, false);
+      case PUT:
+        return createUpdateJob(ctx, true);
+      case DELETE:
+        return deleteJob(ctx);
+    }
+
+    return null;
+  }
+
+  /**
+   * Delete job from metadata repository.
+   *
+   * @param ctx Context object
+   * @return Empty bean
+   */
+  private JsonBean deleteJob(RequestContext ctx) {
+    String sxid = ctx.getLastURLElement();
+    long jid = Long.valueOf(sxid);
+
+    Repository repository = RepositoryManager.getRepository();
+    repository.deleteJob(jid);
+
+    return JsonBean.EMPTY_BEAN;
+  }
+
+  /**
+   * Update or create job metadata in repository.
+   *
+   * @param ctx Context object
+   * @return Validation bean object
+   */
+  private JsonBean createUpdateJob(RequestContext ctx, boolean update) {
+//    Check that given ID equals with sent ID, otherwise report an error UPDATE
+//    String sxid = ctx.getLastURLElement();
+//    long xid = Long.valueOf(sxid);
+
+    JobBean bean = new JobBean();
+
+    try {
+      JSONObject json =
+        (JSONObject) JSONValue.parse(ctx.getRequest().getReader());
+      bean.restore(json);
+    } catch (IOException e) {
+      throw new SqoopException(ServerError.SERVER_0003,
+        "Can't read request content", e);
+    }
+
+    // Get job object
+    List<MJob> jobs = bean.getJobs();
+
+    if(jobs.size() != 1) {
+      throw new SqoopException(ServerError.SERVER_0003,
+        "Expected one job metadata but got " + jobs.size());
+    }
+
+    // Job object
+    MJob job = jobs.get(0);
+
+    // Verify that user is not trying to spoof us
+    MJobForms connectorForms
+      = ConnectorManager.getConnectorMetadata(job.getConnectorId())
+      .getJobForms(job.getType());
+    MJobForms frameworkForms = FrameworkManager.getFramework()
+      .getJobForms(job.getType());
+
+    if(!connectorForms.equals(job.getConnectorPart())
+      || !frameworkForms.equals(job.getFrameworkPart())) {
+      throw new SqoopException(ServerError.SERVER_0003,
+        "Detected incorrect form structure");
+    }
+
+    // Get validator objects
+    Validator connectorValidator =
+      ConnectorManager.getConnector(job.getConnectorId()).getValidator();
+    Validator frameworkValidator = FrameworkManager.getValidator();
+
+    // Validate connection object
+    Status conStat
+      = connectorValidator.validate(job.getType(), job.getConnectorPart());
+    Status frmStat
+      = frameworkValidator.validate(job.getType(), job.getFrameworkPart());
+    Status finalStatus = Status.getWorstStatus(conStat, frmStat);
+
+    // If we're good enough let's perform the action
+    if(finalStatus.canProceed()) {
+      if(update) {
+        RepositoryManager.getRepository().updateJob(job);
+      } else {
+        RepositoryManager.getRepository().createJob(job);
+      }
+    }
+
+    // Return back validations in all cases
+    return new ValidationBean(job, finalStatus);
+  }
+
+  private JsonBean getJobs(RequestContext ctx) {
+    String sjid = ctx.getLastURLElement();
+    JobBean bean;
+
+    Locale locale = ctx.getAcceptLanguageHeader();
+    Repository repository = RepositoryManager.getRepository();
+
+    if (sjid.equals("all")) {
+
+      List<MJob> jobs = repository.findJobs();
+      bean = new JobBean(jobs);
+
+      // Add associated resources into the bean
+      for( MJob job : jobs) {
+        long connectorId = job.getConnectorId();
+        if(!bean.hasConnectorBundle(connectorId)) {
+          bean.addConnectorBundle(connectorId,
+            ConnectorManager.getResourceBundle(connectorId, locale));
+        }
+      }
+    } else {
+      long jid = Long.valueOf(sjid);
+
+      MJob job = repository.findJob(jid);
+      long connectorId = job.getConnectorId();
+
+      bean = new JobBean(job);
+
+      bean.addConnectorBundle(connectorId,
+        ConnectorManager.getResourceBundle(connectorId, locale));
+    }
+
+    // Sent framework resource bundle in all cases
+    bean.setFrameworkBundle(FrameworkManager.getBundle(locale));
+
+    return bean;
+  }
+}

http://git-wip-us.apache.org/repos/asf/sqoop/blob/866d46df/server/src/main/java/org/apache/sqoop/server/v1/JobServlet.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/sqoop/server/v1/JobServlet.java b/server/src/main/java/org/apache/sqoop/server/v1/JobServlet.java
new file mode 100644
index 0000000..34a0ffb
--- /dev/null
+++ b/server/src/main/java/org/apache/sqoop/server/v1/JobServlet.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sqoop.server.v1;
+
+import org.apache.sqoop.handler.JobRequestHandler;
+import org.apache.sqoop.json.JsonBean;
+import org.apache.sqoop.server.RequestContext;
+import org.apache.sqoop.server.RequestHandler;
+import org.apache.sqoop.server.SqoopProtocolServlet;
+
+/**
+ *
+ */
+public class JobServlet extends SqoopProtocolServlet {
+
+  private RequestHandler requestHandler;
+
+  public JobServlet() {
+    requestHandler = new JobRequestHandler();
+  }
+
+  @Override
+  protected JsonBean handleGetRequest(RequestContext ctx) throws Exception {
+    return requestHandler.handleEvent(ctx);
+  }
+
+  @Override
+  protected JsonBean handlePostRequest(RequestContext ctx) throws Exception {
+    return requestHandler.handleEvent(ctx);
+  }
+
+  @Override
+  protected JsonBean handlePutRequest(RequestContext ctx) throws Exception {
+    return requestHandler.handleEvent(ctx);
+  }
+
+  @Override
+  protected JsonBean handleDeleteRequest(RequestContext ctx) throws Exception {
+    return requestHandler.handleEvent(ctx);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sqoop/blob/866d46df/server/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/server/src/main/webapp/WEB-INF/web.xml b/server/src/main/webapp/WEB-INF/web.xml
index f0af9ce..69229bf 100644
--- a/server/src/main/webapp/WEB-INF/web.xml
+++ b/server/src/main/webapp/WEB-INF/web.xml
@@ -75,5 +75,17 @@ limitations under the License.
     <url-pattern>/v1/connection/*</url-pattern>
   </servlet-mapping>
 
+  <!-- Job servlet -->
+  <servlet>
+    <servlet-name>v1.JobServlet</servlet-name>
+    <servlet-class>org.apache.sqoop.server.v1.JobServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>v1.JobServlet</servlet-name>
+    <url-pattern>/v1/job/*</url-pattern>
+  </servlet-mapping>
+
 </web-app>
 

http://git-wip-us.apache.org/repos/asf/sqoop/blob/866d46df/spi/src/main/java/org/apache/sqoop/validation/Validator.java
----------------------------------------------------------------------
diff --git a/spi/src/main/java/org/apache/sqoop/validation/Validator.java b/spi/src/main/java/org/apache/sqoop/validation/Validator.java
index b411ffc..185efd3 100644
--- a/spi/src/main/java/org/apache/sqoop/validation/Validator.java
+++ b/spi/src/main/java/org/apache/sqoop/validation/Validator.java
@@ -19,6 +19,7 @@ package org.apache.sqoop.validation;
 
 import org.apache.sqoop.model.MConnectionForms;
 import org.apache.sqoop.model.MForm;
+import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MJobForms;
 
 import java.util.List;
@@ -104,7 +105,7 @@ public class Validator {
    * @param job Job to be validated
    * @return Validation status
    */
-  public Status validate(MJobForms job) {
+  public Status validate(MJob.Type type, MJobForms job) {
     return validate(job.getForms());
   }