Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 02835200C01 for ; Thu, 5 Jan 2017 01:04:47 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 01471160B47; Thu, 5 Jan 2017 00:04:47 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 31FC3160B52 for ; Thu, 5 Jan 2017 01:04:44 +0100 (CET) Received: (qmail 29204 invoked by uid 500); 5 Jan 2017 00:04:43 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 28601 invoked by uid 99); 5 Jan 2017 00:04:42 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Jan 2017 00:04:42 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 74D72DFB3D; Thu, 5 Jan 2017 00:04:42 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ncole@apache.org To: commits@ambari.apache.org Date: Thu, 05 Jan 2017 00:04:53 -0000 Message-Id: <2e47bb56ac8747d7893345aececb0b03@git.apache.org> In-Reply-To: <4560a958b6084075b468a9a94d10bddd@git.apache.org> References: <4560a958b6084075b468a9a94d10bddd@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [12/50] [abbrv] ambari git commit: AMBARI-19321 : Hive View 2.0 - Minimal view for Hive which includes new UI changes. Also made changes in poms as required (nitirajrathore) archived-at: Thu, 05 Jan 2017 00:04:47 -0000 http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java new file mode 100644 index 0000000..a2c9396 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java @@ -0,0 +1,175 @@ +/** + * 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.ambari.view.hive20.resources.jobs.atsJobs; + +import org.apache.ambari.view.ViewContext; +import org.apache.commons.io.IOUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; + +public class ATSRequestsDelegateImpl implements ATSRequestsDelegate { + protected final static Logger LOG = + LoggerFactory.getLogger(ATSRequestsDelegateImpl.class); + public static final String EMPTY_ENTITIES_JSON = "{ \"entities\" : [ ] }"; + + private ViewContext context; + private String atsUrl; + + public ATSRequestsDelegateImpl(ViewContext context, String atsUrl) { + this.context = context; + this.atsUrl = addProtocolIfMissing(atsUrl); + } + + private String addProtocolIfMissing(String atsUrl) { + if (!atsUrl.matches("^[^:]+://.*$")) + atsUrl = "http://" + atsUrl; + return atsUrl; + } + + @Override + public String hiveQueryIdDirectUrl(String entity) { + return atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID/" + entity; + } + + @Override + public String hiveQueryIdOperationIdUrl(String operationId) { + // ATS parses operationId started with digit as integer and not returns the response. + // Quotation prevents this. + return atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID?primaryFilter=operationid:%22" + operationId + "%22"; + } + + @Override + public String tezDagDirectUrl(String entity) { + return atsUrl + "/ws/v1/timeline/TEZ_DAG_ID/" + entity; + } + + @Override + public String tezDagNameUrl(String name) { + return atsUrl + "/ws/v1/timeline/TEZ_DAG_ID?primaryFilter=dagName:" + name; + } + + @Override + public String tezVerticesListForDAGUrl(String dagId) { + return atsUrl + "/ws/v1/timeline/TEZ_VERTEX_ID?primaryFilter=TEZ_DAG_ID:" + dagId; + } + + @Override + public JSONObject hiveQueryIdsForUser(String username) { + String hiveQueriesListUrl = atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID?primaryFilter=requestuser:" + username; + String response = readFromWithDefault(hiveQueriesListUrl, "{ \"entities\" : [ ] }"); + return (JSONObject) JSONValue.parse(response); + } + + @Override + public JSONObject hiveQueryIdByOperationId(String operationId) { + String hiveQueriesListUrl = hiveQueryIdOperationIdUrl(operationId); + String response = readFromWithDefault(hiveQueriesListUrl, EMPTY_ENTITIES_JSON); + return (JSONObject) JSONValue.parse(response); + } + + @Override + public JSONObject tezDagByName(String name) { + String tezDagUrl = tezDagNameUrl(name); + String response = readFromWithDefault(tezDagUrl, EMPTY_ENTITIES_JSON); + return (JSONObject) JSONValue.parse(response); + } + + @Override + public JSONObject tezDagByEntity(String entity) { + String tezDagEntityUrl = tezDagEntityUrl(entity); + String response = readFromWithDefault(tezDagEntityUrl, EMPTY_ENTITIES_JSON); + return (JSONObject) JSONValue.parse(response); + } + + /** + * fetches the HIVE_QUERY_ID from ATS for given user between given time period + * @param username: username for which to fetch hive query IDs + * @param startTime: time in miliseconds, inclusive + * @param endTime: time in miliseconds, exclusive + * @return + */ + @Override + public JSONObject hiveQueryIdsForUserByTime(String username, long startTime, long endTime) { + StringBuilder url = new StringBuilder(); + url.append(atsUrl).append("/ws/v1/timeline/HIVE_QUERY_ID?") + .append("windowStart=").append(startTime) + .append("&windowEnd=").append(endTime) + .append("&primaryFilter=requestuser:").append(username); + String hiveQueriesListUrl = url.toString(); + + String response = readFromWithDefault(hiveQueriesListUrl, EMPTY_ENTITIES_JSON); + return (JSONObject) JSONValue.parse(response); + } + + @Override + public JSONObject hiveQueryEntityByEntityId(String hiveEntityId) { + StringBuilder url = new StringBuilder(); + url.append(atsUrl).append("/ws/v1/timeline/HIVE_QUERY_ID/").append(hiveEntityId); + String hiveQueriesListUrl = url.toString(); + String response = readFromWithDefault(hiveQueriesListUrl, EMPTY_ENTITIES_JSON); + return (JSONObject) JSONValue.parse(response); + } + + private String tezDagEntityUrl(String entity) { + return atsUrl + "/ws/v1/timeline/TEZ_DAG_ID?primaryFilter=callerId:" + entity; + } + + public boolean checkATSStatus() throws IOException { + String url = atsUrl + "/ws/v1/timeline/"; + InputStream responseInputStream = context.getURLStreamProvider().readAsCurrent(url, "GET", + (String)null, new HashMap()); + IOUtils.toString(responseInputStream); + return true; + } + + @Override + public JSONObject tezVerticesListForDAG(String dagId) { + String response = readFromWithDefault(tezVerticesListForDAGUrl(dagId), "{ \"entities\" : [ ] }"); + return (JSONObject) JSONValue.parse(response); + } + + + + protected String readFromWithDefault(String atsUrl, String defaultResponse) { + String response; + try { + InputStream responseInputStream = context.getURLStreamProvider().readAsCurrent(atsUrl, "GET", + (String)null, new HashMap()); + response = IOUtils.toString(responseInputStream); + } catch (IOException e) { + LOG.error("Error while reading from ATS", e); + response = defaultResponse; + } + return response; + } + + public String getAtsUrl() { + return atsUrl; + } + + public void setAtsUrl(String atsUrl) { + this.atsUrl = atsUrl; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/HiveQueryId.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/HiveQueryId.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/HiveQueryId.java new file mode 100644 index 0000000..cb261d1 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/HiveQueryId.java @@ -0,0 +1,42 @@ +/** + * 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.ambari.view.hive20.resources.jobs.atsJobs; + +import org.json.simple.JSONObject; + +import java.util.List; + +public class HiveQueryId { + public static long ATS_15_RESPONSE_VERSION = 2; // version returned from ATS 1.5 release + + public String url; + + public String entity; + public String query; + + public List dagNames; + + public List stages; + + public long starttime; + public long duration; + public String operationId; + public String user; + public long version; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/IATSParser.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/IATSParser.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/IATSParser.java new file mode 100644 index 0000000..e925bb0 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/IATSParser.java @@ -0,0 +1,39 @@ +/** + * 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.ambari.view.hive20.resources.jobs.atsJobs; + +import java.util.List; + +public interface IATSParser { + List getHiveQueryIdsForUser(String username); + + List getVerticesForDAGId(String dagId); + + HiveQueryId getHiveQueryIdByOperationId(String guidString); + + TezDagId getTezDAGByName(String name); + + TezDagId getTezDAGByEntity(String entity); + + List getHiveQueryIdsForUserByTime(String username, long startTime, long endTime); + + HiveQueryId getHiveQueryIdByHiveEntityId(String hiveEntityId); + + List getHiveQueryIdByEntityList(List hiveEntityIds); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezDagId.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezDagId.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezDagId.java new file mode 100644 index 0000000..184436c --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezDagId.java @@ -0,0 +1,26 @@ +/** + * 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.ambari.view.hive20.resources.jobs.atsJobs; + +public class TezDagId { + public static final String STATUS_UNKNOWN = "UNKNOWN"; + public String applicationId = ""; + public String entity = ""; + public String status = STATUS_UNKNOWN; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezVertexId.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezVertexId.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezVertexId.java new file mode 100644 index 0000000..8acd683 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/atsJobs/TezVertexId.java @@ -0,0 +1,24 @@ +/** + * 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.ambari.view.hive20.resources.jobs.atsJobs; + +public class TezVertexId { + public String entity; + public String vertexName; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParser.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParser.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParser.java new file mode 100644 index 0000000..ee96e05 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParser.java @@ -0,0 +1,129 @@ +/** + * 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.ambari.view.hive20.resources.jobs.rm; + +import org.apache.ambari.view.hive20.resources.jobs.atsJobs.TezVertexId; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Parser of Resource Manager responses + */ +public class RMParser { + protected final static Logger LOG = + LoggerFactory.getLogger(RMParser.class); + private RMRequestsDelegate delegate; + + public RMParser(RMRequestsDelegate delegate) { + this.delegate = delegate; + } + + /** + * Progress of DAG + * @param appId App Id + * @param dagId DAG Id + * @return progress of DAG + */ + public Double getDAGProgress(String appId, String dagId) { + String dagIdx = parseDagIdIndex(dagId); + JSONObject progresses = delegate.dagProgress(appId, dagIdx); + + double dagProgressValue; + if (progresses != null) { + JSONObject dagProgress = (JSONObject) progresses.get("dagProgress"); + dagProgressValue = (Double) (dagProgress.get("progress")); + } else { + LOG.error("Error while retrieving progress of " + appId + ":" + dagId + ". 0 assumed."); + dagProgressValue = 0; + } + return dagProgressValue; + } + + /** + * Progress of vertices + * @param appId App Id + * @param dagId DAG Id + * @param vertices vertices list + * @return list of vertices + */ + public List getDAGVerticesProgress(String appId, String dagId, List vertices) { + String dagIdx = parseDagIdIndex(dagId); + + Map vertexIdToEntityMapping = new HashMap(); + StringBuilder builder = new StringBuilder(); + if (vertices.size() > 0) { + for (TezVertexId vertexId : vertices) { + String[] parts = vertexId.entity.split("_"); + String vertexIdx = parts[parts.length - 1]; + builder.append(vertexIdx).append(","); + + vertexIdToEntityMapping.put(vertexId.entity, vertexId.vertexName); + } + builder.setLength(builder.length() - 1); // remove last comma + } + + String commaSeparatedVertices = builder.toString(); + + List parsedVertexProgresses = new LinkedList(); + JSONObject vertexProgressesResponse = delegate.verticesProgress( + appId, dagIdx, commaSeparatedVertices); + if (vertexProgressesResponse == null) { + LOG.error("Error while retrieving progress of vertices " + + appId + ":" + dagId + ":" + commaSeparatedVertices + ". 0 assumed for all vertices."); + for (TezVertexId vertexId : vertices) { + VertexProgress vertexProgressInfo = new VertexProgress(); + vertexProgressInfo.name = vertexId.vertexName; + vertexProgressInfo.progress = 0.0; + parsedVertexProgresses.add(vertexProgressInfo); + } + return parsedVertexProgresses; + } + JSONArray vertexProgresses = (JSONArray) vertexProgressesResponse.get("vertexProgresses"); + + for (Object vertex : vertexProgresses) { + JSONObject jsonObject = (JSONObject) vertex; + + VertexProgress vertexProgressInfo = new VertexProgress(); + vertexProgressInfo.id = (String) jsonObject.get("id"); + vertexProgressInfo.name = vertexIdToEntityMapping.get(vertexProgressInfo.id); + vertexProgressInfo.progress = (Double) jsonObject.get("progress"); + + parsedVertexProgresses.add(vertexProgressInfo); + } + return parsedVertexProgresses; + } + + public String parseDagIdIndex(String dagId) { + String[] dagIdParts = dagId.split("_"); + return dagIdParts[dagIdParts.length - 1]; + } + + public static class VertexProgress { + public String id; + public String name; + public Double progress; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParserFactory.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParserFactory.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParserFactory.java new file mode 100644 index 0000000..64f268a --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMParserFactory.java @@ -0,0 +1,48 @@ +/** + * 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.ambari.view.hive20.resources.jobs.rm; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.utils.ambari.AmbariApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RMParserFactory { + protected final static Logger LOG = + LoggerFactory.getLogger(RMParserFactory.class); + + private final ViewContext context; + private final AmbariApi ambariApi; + + public RMParserFactory(ViewContext context) { + this.context = context; + this.ambariApi = new AmbariApi(context); + } + + public RMParser getRMParser() { + String rmUrl = getRMUrl(); + + RMRequestsDelegate delegate = new RMRequestsDelegateImpl(context, rmUrl); + return new RMParser(delegate); + } + + public String getRMUrl() { + return ambariApi.getServices().getRMUrl(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegate.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegate.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegate.java new file mode 100644 index 0000000..e661833 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegate.java @@ -0,0 +1,31 @@ +/** + * 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.ambari.view.hive20.resources.jobs.rm; + +import org.json.simple.JSONObject; + +public interface RMRequestsDelegate { + String dagProgressUrl(String appId, String dagIdx); + + String verticesProgressUrl(String appId, String dagIdx, String vertices); + + JSONObject dagProgress(String appId, String dagIdx); + + JSONObject verticesProgress(String appId, String dagIdx, String commaSeparatedVertices); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegateImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegateImpl.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegateImpl.java new file mode 100644 index 0000000..ed07b55 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/rm/RMRequestsDelegateImpl.java @@ -0,0 +1,99 @@ +/** + * 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.ambari.view.hive20.resources.jobs.rm; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.hive20.utils.ServiceFormattedException; +import org.apache.commons.io.IOUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; + +public class RMRequestsDelegateImpl implements RMRequestsDelegate { + protected final static Logger LOG = + LoggerFactory.getLogger(RMRequestsDelegateImpl.class); + public static final String EMPTY_ENTITIES_JSON = "{ \"entities\" : [ ] }"; + + private ViewContext context; + private String rmUrl; + + public RMRequestsDelegateImpl(ViewContext context, String rmUrl) { + this.context = context; + this.rmUrl = rmUrl; + } + + @Override + public String dagProgressUrl(String appId, String dagIdx) { + return rmUrl + String.format("/proxy/%s/ws/v1/tez/dagProgress?dagID=%s", appId, dagIdx); + } + + @Override + public String verticesProgressUrl(String appId, String dagIdx, String vertices) { + return rmUrl + String.format("/proxy/%s/ws/v1/tez/vertexProgresses?dagID=%s&vertexID=%s", appId, dagIdx, vertices); + } + + @Override + public JSONObject dagProgress(String appId, String dagIdx) { + String url = dagProgressUrl(appId, dagIdx); + String response; + try { + InputStream responseInputStream = context.getURLStreamProvider().readFrom(url, "GET", + (String)null, new HashMap()); + response = IOUtils.toString(responseInputStream); + } catch (IOException e) { + throw new ServiceFormattedException( + String.format("R010 DAG %s in app %s not found or ResourceManager is unreachable", dagIdx, appId)); + } + return (JSONObject) JSONValue.parse(response); + } + + @Override + public JSONObject verticesProgress(String appId, String dagIdx, String commaSeparatedVertices) { + String url = verticesProgressUrl(appId, dagIdx, commaSeparatedVertices); + String response; + try { + InputStream responseInputStream = context.getURLStreamProvider().readFrom(url, "GET", + (String)null, new HashMap()); + response = IOUtils.toString(responseInputStream); + } catch (IOException e) { + throw new ServiceFormattedException( + String.format("R020 DAG %s in app %s not found or ResourceManager is unreachable", dagIdx, appId)); + } + return (JSONObject) JSONValue.parse(response); + } + + protected String readFromWithDefault(String url, String defaultResponse) { + String response; + try { + InputStream responseInputStream = context.getURLStreamProvider().readFrom(url, "GET", + (String)null, new HashMap()); + response = IOUtils.toString(responseInputStream); + } catch (IOException e) { + LOG.error("Error while reading from RM", e); + response = defaultResponse; + } + return response; + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/IJobControllerFactory.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/IJobControllerFactory.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/IJobControllerFactory.java new file mode 100644 index 0000000..b11f124 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/IJobControllerFactory.java @@ -0,0 +1,23 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + +public interface IJobControllerFactory { + JobController createControllerForJob(Job job); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/Job.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/Job.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/Job.java new file mode 100644 index 0000000..d64e354 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/Job.java @@ -0,0 +1,131 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + + +import org.apache.ambari.view.hive20.persistence.utils.Indexed; +import org.apache.ambari.view.hive20.persistence.utils.PersonalResource; + +import java.io.Serializable; + +/** + * Interface for ExecuteJob bean to create Proxy for it + */ +public interface Job extends Serializable,Indexed,PersonalResource { + String JOB_STATE_UNKNOWN = "UNKNOWN"; + String JOB_STATE_INITIALIZED = "INITIALIZED"; + String JOB_STATE_RUNNING = "RUNNING"; + String JOB_STATE_FINISHED = "SUCCEEDED"; + String JOB_STATE_CANCELED = "CANCELED"; + String JOB_STATE_CLOSED = "CLOSED"; + String JOB_STATE_ERROR = "ERROR"; + String JOB_STATE_PENDING = "PENDING"; + + String getId(); + + void setId(String id); + + String getOwner(); + + void setOwner(String owner); + + String getTitle(); + + void setTitle(String title); + + String getQueryFile(); + + void setQueryFile(String queryFile); + + Long getDateSubmitted(); + + void setDateSubmitted(Long dateSubmitted); + + Long getDuration(); + + void setDuration(Long duration); + + String getStatus(); + + void setStatus(String status); + + String getForcedContent(); + + void setForcedContent(String forcedContent); + + String getQueryId(); + + void setQueryId(String queryId); + + String getStatusDir(); + + void setStatusDir(String statusDir); + + String getDataBase(); + + void setDataBase(String dataBase); + + String getLogFile(); + + void setLogFile(String logFile); + + String getConfFile(); + + void setConfFile(String confFile); + + String getApplicationId(); + + void setApplicationId(String applicationId); + + String getDagName(); + + void setDagName(String dagName); + + String getDagId(); + + void setDagId(String dagId); + + String getSessionTag(); + + void setSessionTag(String sessionTag); + + String getSqlState(); + + void setSqlState(String sqlState); + + String getStatusMessage(); + + void setStatusMessage(String message); + + String getReferrer(); + + void setReferrer(String referrer); + + String getGlobalSettings(); + + void setGlobalSettings(String globalSettings); + + String getGuid(); + + void setGuid(String guid); + + String getHiveQueryId(); + + void setHiveQueryId(String hiveQueryId); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobController.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobController.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobController.java new file mode 100644 index 0000000..e8a2fe3 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobController.java @@ -0,0 +1,44 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; + +public interface JobController { + + void submit() throws Throwable; + + void cancel() throws ItemNotFound; + + Job getJob(); + + /** + * Use carefully. Returns unproxied bean object + * @return unproxied bean object + */ + Job getJobPOJO(); + + void afterCreation(); + + void update(); + + boolean isModified(); + + void clearModified(); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerFactory.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerFactory.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerFactory.java new file mode 100644 index 0000000..cc79843 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerFactory.java @@ -0,0 +1,40 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.hive20.utils.SharedObjectsFactory; + +public class JobControllerFactory implements IJobControllerFactory { + private SharedObjectsFactory sharedObjectsFactory; + private ViewContext context; + + public JobControllerFactory(ViewContext context, SharedObjectsFactory sharedObjectsFactory) { + this.sharedObjectsFactory = sharedObjectsFactory; + this.context = context; + } + + @Override + public JobController createControllerForJob(Job job) { + return new JobControllerImpl(context, job, + sharedObjectsFactory.getSavedQueryResourceManager(), + sharedObjectsFactory.getATSParser(), + sharedObjectsFactory.getHdfsApi()); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerImpl.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerImpl.java new file mode 100644 index 0000000..1511e5b --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobControllerImpl.java @@ -0,0 +1,311 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.hive20.ConnectionFactory; +import org.apache.ambari.view.hive20.ConnectionSystem; +import org.apache.ambari.view.hive20.actor.message.HiveJob; +import org.apache.ambari.view.hive20.actor.message.SQLStatementJob; +import org.apache.ambari.view.hive20.client.AsyncJobRunner; +import org.apache.ambari.view.hive20.client.AsyncJobRunnerImpl; +import org.apache.ambari.view.hive20.client.ConnectionConfig; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.resources.jobs.ModifyNotificationDelegate; +import org.apache.ambari.view.hive20.resources.jobs.ModifyNotificationInvocationHandler; +import org.apache.ambari.view.hive20.resources.jobs.atsJobs.IATSParser; +import org.apache.ambari.view.hive20.resources.savedQueries.SavedQuery; +import org.apache.ambari.view.hive20.resources.savedQueries.SavedQueryResourceManager; +import org.apache.ambari.view.hive20.utils.BadRequestFormattedException; +import org.apache.ambari.view.hive20.utils.FilePaginator; +import org.apache.ambari.view.hive20.utils.MisconfigurationFormattedException; +import org.apache.ambari.view.hive20.utils.ServiceFormattedException; +import org.apache.ambari.view.utils.hdfs.HdfsApi; +import org.apache.ambari.view.utils.hdfs.HdfsApiException; +import org.apache.ambari.view.utils.hdfs.HdfsUtil; +import org.apache.commons.lang3.ArrayUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.Proxy; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class JobControllerImpl implements JobController, ModifyNotificationDelegate { + private final static Logger LOG = + LoggerFactory.getLogger(JobControllerImpl.class); + + private ViewContext context; + private HdfsApi hdfsApi; + private Job jobUnproxied; + private Job job; + private boolean modified; + + private SavedQueryResourceManager savedQueryResourceManager; + private IATSParser atsParser; + + /** + * JobController constructor + * Warning: Create JobControllers ONLY using JobControllerFactory! + */ + public JobControllerImpl(ViewContext context, Job job, + SavedQueryResourceManager savedQueryResourceManager, + IATSParser atsParser, + HdfsApi hdfsApi) { + this.context = context; + setJobPOJO(job); + this.savedQueryResourceManager = savedQueryResourceManager; + this.atsParser = atsParser; + this.hdfsApi = hdfsApi; + + } + + public String getQueryForJob() { + FilePaginator paginator = new FilePaginator(job.getQueryFile(), hdfsApi); + String query; + try { + query = paginator.readPage(0); //warning - reading only 0 page restricts size of query to 1MB + } catch (IOException e) { + throw new ServiceFormattedException("F030 Error when reading file " + job.getQueryFile(), e); + } catch (InterruptedException e) { + throw new ServiceFormattedException("F030 Error when reading file " + job.getQueryFile(), e); + } + return query; + } + + private static final String DEFAULT_DB = "default"; + + public String getJobDatabase() { + if (job.getDataBase() != null) { + return job.getDataBase(); + } else { + return DEFAULT_DB; + } + } + + + @Override + public void submit() throws Throwable { + String jobDatabase = getJobDatabase(); + String query = getQueryForJob(); + ConnectionSystem system = ConnectionSystem.getInstance(); + AsyncJobRunner asyncJobRunner = new AsyncJobRunnerImpl(context, system.getOperationController(context), system.getActorSystem()); + SQLStatementJob asyncJob = new SQLStatementJob(HiveJob.Type.ASYNC, getStatements(jobDatabase, query), context.getUsername(), job.getId(), job.getLogFile()); + asyncJobRunner.submitJob(getHiveConnectionConfig(), asyncJob, job); + + } + + private String[] getStatements(String jobDatabase, String query) { + String[] queries = query.split(";"); + + + String[] strings = {"use " + jobDatabase}; + return ArrayUtils.addAll(strings, queries); + } + + + @Override + public void cancel() throws ItemNotFound { + ConnectionSystem system = ConnectionSystem.getInstance(); + AsyncJobRunner asyncJobRunner = new AsyncJobRunnerImpl(context, system.getOperationController(context), system.getActorSystem()); + asyncJobRunner.cancelJob(job.getId(), context.getUsername()); + } + + @Override + public void update() { + updateJobDuration(); + } + + + @Override + public Job getJob() { + return job; + } + + /** + * Use carefully. Returns unproxied bean object + * @return unproxied bean object + */ + @Override + public Job getJobPOJO() { + return jobUnproxied; + } + + public void setJobPOJO(Job jobPOJO) { + Job jobModifyNotificationProxy = (Job) Proxy.newProxyInstance(jobPOJO.getClass().getClassLoader(), + new Class[]{Job.class}, + new ModifyNotificationInvocationHandler(jobPOJO, this)); + this.job = jobModifyNotificationProxy; + + this.jobUnproxied = jobPOJO; + } + + + @Override + public void afterCreation() { + setupStatusDirIfNotPresent(); + setupQueryFileIfNotPresent(); + setupLogFileIfNotPresent(); + + setCreationDate(); + } + + public void setupLogFileIfNotPresent() { + if (job.getLogFile() == null || job.getLogFile().isEmpty()) { + setupLogFile(); + } + } + + public void setupQueryFileIfNotPresent() { + if (job.getQueryFile() == null || job.getQueryFile().isEmpty()) { + setupQueryFile(); + } + } + + public void setupStatusDirIfNotPresent() { + if (job.getStatusDir() == null || job.getStatusDir().isEmpty()) { + setupStatusDir(); + } + } + + private static final long MillisInSecond = 1000L; + + public void updateJobDuration() { + job.setDuration((System.currentTimeMillis() / MillisInSecond) - (job.getDateSubmitted() / MillisInSecond)); + } + + public void setCreationDate() { + job.setDateSubmitted(System.currentTimeMillis()); + } + + private void setupLogFile() { + LOG.debug("Creating log file for job#" + job.getId()); + + String logFile = job.getStatusDir() + "/" + "logs"; + try { + HdfsUtil.putStringToFile(hdfsApi, logFile, ""); + } catch (HdfsApiException e) { + throw new ServiceFormattedException(e); + } + + job.setLogFile(logFile); + LOG.debug("Log file for job#" + job.getId() + ": " + logFile); + } + + private void setupStatusDir() { + String newDirPrefix = makeStatusDirectoryPrefix(); + String newDir = null; + try { + newDir = HdfsUtil.findUnallocatedFileName(hdfsApi, newDirPrefix, ""); + } catch (HdfsApiException e) { + throw new ServiceFormattedException(e); + } + + job.setStatusDir(newDir); + LOG.debug("Status dir for job#" + job.getId() + ": " + newDir); + } + + private String makeStatusDirectoryPrefix() { + String userScriptsPath = context.getProperties().get("jobs.dir"); + + if (userScriptsPath == null) { // TODO: move check to initialization code + String msg = "jobs.dir is not configured!"; + LOG.error(msg); + throw new MisconfigurationFormattedException("jobs.dir"); + } + + String normalizedName = String.format("hive-job-%s", job.getId()); + String timestamp = new SimpleDateFormat("yyyy-MM-dd_hh-mm").format(new Date()); + return String.format(userScriptsPath + + "/%s-%s", normalizedName, timestamp); + } + + private void setupQueryFile() { + String statusDir = job.getStatusDir(); + assert statusDir != null : "setupStatusDir() should be called first"; + + String jobQueryFilePath = statusDir + "/" + "query.hql"; + + try { + + if (job.getForcedContent() != null) { + + HdfsUtil.putStringToFile(hdfsApi, jobQueryFilePath, job.getForcedContent()); + job.setForcedContent(""); // prevent forcedContent to be written to DB + + } else if (job.getQueryId() != null) { + + String savedQueryFile = getRelatedSavedQueryFile(); + hdfsApi.copy(savedQueryFile, jobQueryFilePath); + job.setQueryFile(jobQueryFilePath); + + } else { + + throw new BadRequestFormattedException("queryId or forcedContent should be passed!", null); + + } + + } catch (IOException e) { + throw new ServiceFormattedException("F040 Error when creating file " + jobQueryFilePath, e); + } catch (InterruptedException e) { + throw new ServiceFormattedException("F040 Error when creating file " + jobQueryFilePath, e); + } catch (HdfsApiException e) { + throw new ServiceFormattedException(e); + } + job.setQueryFile(jobQueryFilePath); + + LOG.debug("Query file for job#" + job.getId() + ": " + jobQueryFilePath); + } + + + private ConnectionConfig getHiveConnectionConfig() { + return ConnectionFactory.create(context); + } + + private String getRelatedSavedQueryFile() { + SavedQuery savedQuery; + try { + savedQuery = savedQueryResourceManager.read(job.getQueryId()); + } catch (ItemNotFound itemNotFound) { + throw new BadRequestFormattedException("queryId not found!", itemNotFound); + } + return savedQuery.getQueryFile(); + } + + @Override + public boolean onModification(Object object) { + setModified(true); + return true; + } + + @Override + public boolean isModified() { + return modified; + } + + public void setModified(boolean modified) { + this.modified = modified; + } + + @Override + public void clearModified() { + setModified(false); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobImpl.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobImpl.java new file mode 100644 index 0000000..85ffaf2 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobImpl.java @@ -0,0 +1,335 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + +import org.apache.commons.beanutils.PropertyUtils; + +import java.beans.Transient; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + +/** + * Bean to represent saved query + */ +public class JobImpl implements Job { + private String title = null; + private String queryFile = null; + private String statusDir = null; + private Long dateSubmitted = 0L; + private Long duration = 0L; + private String forcedContent = null; + private String dataBase = null; + private String queryId = null; + + private String status = JOB_STATE_UNKNOWN; + private String statusMessage = null; + private String sqlState = null; + + private String applicationId; + private String dagId; + private String dagName; + + private String sessionTag; + private String referrer; + private String globalSettings; + + private String id = null; + private String owner = null; + + private String logFile; + private String confFile; + + private String guid = null; + + private String hiveQueryId; + + public JobImpl() {} + public JobImpl(Map stringObjectMap) throws InvocationTargetException, IllegalAccessException { + for (Map.Entry entry : stringObjectMap.entrySet()) { + try { + PropertyUtils.setProperty(this, entry.getKey(), entry.getValue()); + } catch (NoSuchMethodException e) { + //do nothing, skip + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Job)) return false; + + JobImpl job = (JobImpl) o; + + return id != null ? id.equals(job.id) : job.id == null; + + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } + + @Override + @Transient + public String getHiveQueryId() { + return hiveQueryId; + } + + @Override + @Transient + public void setHiveQueryId(String hiveQueryId) { + this.hiveQueryId = hiveQueryId; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public String getOwner() { + return owner; + } + + @Override + public void setOwner(String owner) { + this.owner = owner; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public String getQueryFile() { + return queryFile; + } + + @Override + public void setQueryFile(String queryFile) { + this.queryFile = queryFile; + } + + @Override + public Long getDateSubmitted() { + return dateSubmitted; + } + + @Override + public void setDateSubmitted(Long dateSubmitted) { + this.dateSubmitted = dateSubmitted; + } + + @Override + public Long getDuration() { + return duration; + } + + @Override + public void setDuration(Long duration) { + this.duration = duration; + } + + @Override + public String getStatus() { + return status; + } + + @Override + public void setStatus(String status) { + this.status = status; + } + + @Override + @Transient + public String getForcedContent() { + return forcedContent; + } + + @Override + @Transient + public void setForcedContent(String forcedContent) { + this.forcedContent = forcedContent; + } + + @Override + public String getQueryId() { + return queryId; + } + + @Override + public void setQueryId(String queryId) { + this.queryId = queryId; + } + + @Override + public String getStatusDir() { + return statusDir; + } + + @Override + public void setStatusDir(String statusDir) { + this.statusDir = statusDir; + } + + @Override + public String getDataBase() { + return dataBase; + } + + @Override + public void setDataBase(String dataBase) { + this.dataBase = dataBase; + } + + @Override + public String getLogFile() { + return logFile; + } + + @Override + public void setLogFile(String logFile) { + this.logFile = logFile; + } + + @Override + public String getConfFile() { + return confFile; + } + + @Override + public void setConfFile(String confFile) { + this.confFile = confFile; + } + + @Override + public String getApplicationId() { + return applicationId; + } + + @Override + public void setApplicationId(String applicationId) { + this.applicationId = applicationId; + } + + @Override + public String getDagName() { + return dagName; + } + + @Override + public void setDagName(String dagName) { + this.dagName = dagName; + } + + @Override + public String getDagId() { + return dagId; + } + + @Override + public void setDagId(String dagId) { + this.dagId = dagId; + } + + @Override + public String getSessionTag() { + return sessionTag; + } + + @Override + public void setSessionTag(String sessionTag) { + this.sessionTag = sessionTag; + } + + @Override + @Transient + public String getStatusMessage() { + return statusMessage; + } + + @Override + @Transient + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } + + @Override + public String getSqlState() { + return sqlState; + } + + @Override + public void setSqlState(String sqlState) { + this.sqlState = sqlState; + } + + @Override + public String getReferrer() { + return referrer; + } + + @Override + public void setReferrer(String referrer) { + this.referrer = referrer; + } + + @Override + public String getGlobalSettings() { + return globalSettings; + } + + @Override + public void setGlobalSettings(String globalSettings) { + this.globalSettings = globalSettings; + } + + @Override + public String getGuid() { + return guid; + } + + @Override + public void setGuid(String guid) { + this.guid = guid; + } + + @Override + public String toString() { + return new StringBuilder("JobImpl{") + .append("id='").append(id) + .append(", owner='").append(owner) + .append(", hiveQueryId='").append(hiveQueryId) + .append(", dagId='").append(dagId) + .append(", queryId='").append(queryId) + .append('}').toString(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobInfo.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobInfo.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobInfo.java new file mode 100644 index 0000000..e4ddc72 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobInfo.java @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.view.hive20.resources.jobs.viewJobs; + +public class JobInfo { + private String jobId; + private String hiveId; + private String dagId; + private String operationId; + + public JobInfo() { + } + + public JobInfo(String jobId, String hiveId, String dagId, String operationId) { + this.jobId = jobId; + this.hiveId = hiveId; + this.dagId = dagId; + this.operationId = operationId; + } + + public String getJobId() { + return jobId; + } + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + public String getHiveId() { + return hiveId; + } + + public void setHiveId(String hiveId) { + this.hiveId = hiveId; + } + + public String getDagId() { + return dagId; + } + + public void setDagId(String dagId) { + this.dagId = dagId; + } + + public String getOperationId() { + return operationId; + } + + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + @Override + public String toString() { + return new StringBuilder().append("JobInfo{" ) + .append("jobId=").append(jobId) + .append(", hiveId=").append(hiveId) + .append(", dagId=").append(dagId) + .append(", operationId=").append(operationId) + .append('}').toString(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobResourceManager.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobResourceManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobResourceManager.java new file mode 100644 index 0000000..1bfdcaa --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/jobs/viewJobs/JobResourceManager.java @@ -0,0 +1,93 @@ +/** + * 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.ambari.view.hive20.resources.jobs.viewJobs; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.hive20.persistence.utils.FilteringStrategy; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.resources.PersonalCRUDResourceManager; +import org.apache.ambari.view.hive20.utils.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * Object that provides CRUD operations for job objects + */ +public class JobResourceManager extends PersonalCRUDResourceManager { + private final static Logger LOG = + LoggerFactory.getLogger(JobResourceManager.class); + + private IJobControllerFactory jobControllerFactory; + + /** + * Constructor + * @param context View Context instance + */ + public JobResourceManager(SharedObjectsFactory sharedObjectsFactory, ViewContext context) { + super(JobImpl.class, sharedObjectsFactory, context); + jobControllerFactory = sharedObjectsFactory.getJobControllerFactory(); + } + + @Override + public Job create(Job object) { + super.create(object); + JobController jobController = jobControllerFactory.createControllerForJob(object); + + try { + + jobController.afterCreation(); + saveIfModified(jobController); + + } catch (ServiceFormattedException e) { + cleanupAfterErrorAndThrowAgain(object, e); + } + + return object; + } + + public void saveIfModified(JobController jobController) { + if (jobController.isModified()) { + save(jobController.getJobPOJO()); + jobController.clearModified(); + } + } + + + @Override + public Job read(Object id) throws ItemNotFound { + return super.read(id); + } + + @Override + public List readAll(FilteringStrategy filteringStrategy) { + return super.readAll(filteringStrategy); + } + + @Override + public void delete(Object resourceId) throws ItemNotFound { + super.delete(resourceId); + } + + public JobController readController(Object id) throws ItemNotFound { + Job job = read(id); + return jobControllerFactory.createControllerForJob(job); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceItem.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceItem.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceItem.java new file mode 100644 index 0000000..f9478be --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceItem.java @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.view.hive20.resources.resources; + +import org.apache.ambari.view.hive20.persistence.utils.PersonalResource; +import org.apache.commons.beanutils.BeanUtils; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + +/** + * Bean to represent file resource + */ +public class FileResourceItem implements Serializable, PersonalResource { + private String name; + private String path; + + private String id; + private String owner; + + public FileResourceItem() {} + public FileResourceItem(Map stringObjectMap) throws InvocationTargetException, IllegalAccessException { + BeanUtils.populate(this, stringObjectMap); + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public String getOwner() { + return owner; + } + + @Override + public void setOwner(String owner) { + this.owner = owner; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceManager.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceManager.java new file mode 100644 index 0000000..bc52158 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceManager.java @@ -0,0 +1,65 @@ +/** + * 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.ambari.view.hive20.resources.resources; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.hive20.persistence.IStorageFactory; +import org.apache.ambari.view.hive20.persistence.utils.FilteringStrategy; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.resources.PersonalCRUDResourceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Object that provides CRUD operations for resource objects + */ +public class FileResourceResourceManager extends PersonalCRUDResourceManager { + private final static Logger LOG = + LoggerFactory.getLogger(FileResourceResourceManager.class); + + /** + * Constructor + * @param context View Context instance + */ + public FileResourceResourceManager(IStorageFactory storageFactory, ViewContext context) { + super(FileResourceItem.class, storageFactory, context); + } + + @Override + public FileResourceItem create(FileResourceItem object) { + return super.create(object); + } + + @Override + public FileResourceItem read(Object id) throws ItemNotFound { + return super.read(id); + } + + @Override + public void delete(Object resourceId) throws ItemNotFound { + super.delete(resourceId); + } + + @Override + public List readAll(FilteringStrategy filteringStrategy) { + return super.readAll(filteringStrategy); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceProvider.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceProvider.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceProvider.java new file mode 100644 index 0000000..411099f --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceResourceProvider.java @@ -0,0 +1,110 @@ +/** + * 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.ambari.view.hive20.resources.resources; + +import org.apache.ambari.view.*; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.persistence.utils.OnlyOwnersFilteringStrategy; +import org.apache.ambari.view.hive20.utils.SharedObjectsFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Resource provider for resource + */ +public class FileResourceResourceProvider implements ResourceProvider { + @Inject + ViewContext context; + + protected FileResourceResourceManager resourceManager = null; + protected final static Logger LOG = + LoggerFactory.getLogger(FileResourceResourceProvider.class); + + protected synchronized FileResourceResourceManager getResourceManager() { + if (resourceManager == null) { + resourceManager = new FileResourceResourceManager(new SharedObjectsFactory(context), context); + } + return resourceManager; + } + + @Override + public FileResourceItem getResource(String resourceId, Set properties) throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + try { + return getResourceManager().read(resourceId); + } catch (ItemNotFound itemNotFound) { + throw new NoSuchResourceException(resourceId); + } + } + + @Override + public Set getResources(ReadRequest readRequest) throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + if (context == null) { + return new HashSet(); + } + return new HashSet(getResourceManager().readAll( + new OnlyOwnersFilteringStrategy(this.context.getUsername()))); + } + + @Override + public void createResource(String s, Map stringObjectMap) throws SystemException, ResourceAlreadyExistsException, NoSuchResourceException, UnsupportedPropertyException { + FileResourceItem item = null; + try { + item = new FileResourceItem(stringObjectMap); + } catch (InvocationTargetException e) { + throw new SystemException("error on creating resource", e); + } catch (IllegalAccessException e) { + throw new SystemException("error on creating resource", e); + } + getResourceManager().create(item); + } + + @Override + public boolean updateResource(String resourceId, Map stringObjectMap) throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + FileResourceItem item = null; + try { + item = new FileResourceItem(stringObjectMap); + } catch (InvocationTargetException e) { + throw new SystemException("error on updating resource", e); + } catch (IllegalAccessException e) { + throw new SystemException("error on updating resource", e); + } + try { + getResourceManager().update(item, resourceId); + } catch (ItemNotFound itemNotFound) { + throw new NoSuchResourceException(resourceId); + } + return true; + } + + @Override + public boolean deleteResource(String resourceId) throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + try { + getResourceManager().delete(resourceId); + } catch (ItemNotFound itemNotFound) { + throw new NoSuchResourceException(resourceId); + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceService.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceService.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceService.java new file mode 100644 index 0000000..3ed8d17 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/resources/FileResourceService.java @@ -0,0 +1,180 @@ +/** + * 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.ambari.view.hive20.resources.resources; + +import org.apache.ambari.view.ViewResourceHandler; +import org.apache.ambari.view.hive20.BaseService; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.persistence.utils.OnlyOwnersFilteringStrategy; +import org.apache.ambari.view.hive20.utils.NotFoundFormattedException; +import org.apache.ambari.view.hive20.utils.ServiceFormattedException; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import java.util.List; + +/** + * Servlet for Resources + * API: + * GET /:id + * read resource + * POST / + * create new resource + * GET / + * get all resource of current user + */ +public class FileResourceService extends BaseService { + @Inject + ViewResourceHandler handler; + + protected FileResourceResourceManager resourceManager = null; + protected final static Logger LOG = + LoggerFactory.getLogger(FileResourceService.class); + + protected synchronized FileResourceResourceManager getResourceManager() { + if (resourceManager == null) { + resourceManager = new FileResourceResourceManager(getSharedObjectsFactory(), context); + } + return resourceManager; + } + + /** + * Get single item + */ + @GET + @Path("{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response getOne(@PathParam("id") String id) { + try { + FileResourceItem fileResourceItem = getResourceManager().read(id); + JSONObject object = new JSONObject(); + object.put("fileResource", fileResourceItem); + return Response.ok(object).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (ItemNotFound itemNotFound) { + throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound); + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Delete single item + */ + @DELETE + @Path("{id}") + public Response delete(@PathParam("id") String id) { + try { + getResourceManager().delete(id); + return Response.status(204).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (ItemNotFound itemNotFound) { + throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound); + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Get all resources + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getList() { + try { + LOG.debug("Getting all resources"); + List items = getResourceManager().readAll( + new OnlyOwnersFilteringStrategy(this.context.getUsername())); //TODO: move strategy to PersonalCRUDRM + + JSONObject object = new JSONObject(); + object.put("fileResources", items); + return Response.ok(object).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Update item + */ + @PUT + @Path("{id}") + @Consumes(MediaType.APPLICATION_JSON) + public Response update(ResourceRequest request, + @PathParam("id") String id) { + try { + getResourceManager().update(request.fileResource, id); + return Response.status(204).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (ItemNotFound itemNotFound) { + throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound); + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Create resource + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response create(ResourceRequest request, @Context HttpServletResponse response, + @Context UriInfo ui) { + try { + getResourceManager().create(request.fileResource); + + FileResourceItem item = null; + + item = getResourceManager().read(request.fileResource.getId()); + + response.setHeader("Location", + String.format("%s/%s", ui.getAbsolutePath().toString(), request.fileResource.getId())); + + JSONObject object = new JSONObject(); + object.put("fileResource", item); + return Response.ok(object).status(201).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (ItemNotFound itemNotFound) { + throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound); + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Wrapper object for json mapping + */ + public static class ResourceRequest { + public FileResourceItem fileResource; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQuery.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQuery.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQuery.java new file mode 100644 index 0000000..cbb4e4a --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQuery.java @@ -0,0 +1,96 @@ +/** + * 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.ambari.view.hive20.resources.savedQueries; + +import org.apache.ambari.view.hive20.persistence.utils.PersonalResource; +import org.apache.commons.beanutils.BeanUtils; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + +/** + * Bean to represent saved query + */ +public class SavedQuery implements Serializable, PersonalResource { + private String queryFile; + private String dataBase; + private String title; + private String shortQuery; + + private String id; + private String owner; + + public SavedQuery() {} + public SavedQuery(Map stringObjectMap) throws InvocationTargetException, IllegalAccessException { + BeanUtils.populate(this, stringObjectMap); + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public String getOwner() { + return owner; + } + + @Override + public void setOwner(String owner) { + this.owner = owner; + } + + public String getQueryFile() { + return queryFile; + } + + public void setQueryFile(String queryFile) { + this.queryFile = queryFile; + } + + public String getDataBase() { + return dataBase; + } + + public void setDataBase(String dataBase) { + this.dataBase = dataBase; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getShortQuery() { + return shortQuery; + } + + public void setShortQuery(String shortQuery) { + this.shortQuery = shortQuery; + } +}