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 A0487200C16 for ; Thu, 5 Jan 2017 01:04:46 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 9D624160B4D; Thu, 5 Jan 2017 00:04:46 +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 1D53D160B51 for ; Thu, 5 Jan 2017 01:04:43 +0100 (CET) Received: (qmail 29082 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 28469 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 70BA8DFC12; 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:52 -0000 Message-Id: <7a3d4212faa645589a862c99acbac7a0@git.apache.org> In-Reply-To: <4560a958b6084075b468a9a94d10bddd@git.apache.org> References: <4560a958b6084075b468a9a94d10bddd@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [11/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:46 -0000 http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceManager.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceManager.java new file mode 100644 index 0000000..ef497ce --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceManager.java @@ -0,0 +1,162 @@ +/** + * 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.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.apache.ambari.view.utils.hdfs.HdfsApiException; +import org.apache.ambari.view.utils.hdfs.HdfsUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * Object that provides CRUD operations for query objects + */ +public class SavedQueryResourceManager extends PersonalCRUDResourceManager { + private final static Logger LOG = + LoggerFactory.getLogger(SavedQueryResourceManager.class); + + private SharedObjectsFactory sharedObjectsFactory; + + /** + * Constructor + * @param context View Context instance + */ + public SavedQueryResourceManager(ViewContext context, SharedObjectsFactory sharedObjectsFactory) { + super(SavedQuery.class, sharedObjectsFactory, context); + this.sharedObjectsFactory = sharedObjectsFactory; + } + + @Override + public SavedQuery create(SavedQuery object) { + object = super.create(object); + try { + + if (object.getQueryFile() == null || object.getQueryFile().isEmpty()) { + createDefaultQueryFile(object); + } + + } catch (ServiceFormattedException e) { + cleanupAfterErrorAndThrowAgain(object, e); + } + return object; + } + + private void createDefaultQueryFile(SavedQuery object) { + String userScriptsPath = context.getProperties().get("scripts.dir"); + if (userScriptsPath == null) { + String msg = "scripts.dir is not configured!"; + LOG.error(msg); + throw new MisconfigurationFormattedException("scripts.dir"); + } + + String normalizedName = String.format("hive-query-%s", object.getId()); + String timestamp = new SimpleDateFormat("yyyy-MM-dd_hh-mm").format(new Date()); + String baseFileName = String.format(userScriptsPath + + "/%s-%s", normalizedName, timestamp); + + String newFilePath = null; + try { + newFilePath = HdfsUtil.findUnallocatedFileName(sharedObjectsFactory.getHdfsApi(), baseFileName, ".hql"); + HdfsUtil.putStringToFile(sharedObjectsFactory.getHdfsApi(), newFilePath, ""); + } catch (HdfsApiException e) { + throw new ServiceFormattedException(e); + } + + object.setQueryFile(newFilePath); + storageFactory.getStorage().store(SavedQuery.class, object); + } + + @Override + public SavedQuery read(Object id) throws ItemNotFound { + SavedQuery savedQuery = super.read(id); + fillShortQueryField(savedQuery); + return savedQuery; + } + + private void fillShortQueryField(SavedQuery savedQuery) { + if (savedQuery.getQueryFile() != null) { + FilePaginator paginator = new FilePaginator(savedQuery.getQueryFile(), sharedObjectsFactory.getHdfsApi()); + String query = null; + try { + query = paginator.readPage(0); + } catch (IOException e) { + LOG.error("Can't read query file " + savedQuery.getQueryFile()); + return; + } catch (InterruptedException e) { + LOG.error("Can't read query file " + savedQuery.getQueryFile()); + return; + } + savedQuery.setShortQuery(makeShortQuery(query)); + } + storageFactory.getStorage().store(SavedQuery.class, savedQuery); + } + + private void emptyShortQueryField(SavedQuery query) { + query.setShortQuery(""); + storageFactory.getStorage().store(SavedQuery.class, query); + } + + /** + * Generate short preview of query. + * Remove SET settings like "set hive.execution.engine=tez;" from beginning + * and trim to 42 symbols. + * @param query full query + * @return shortened query + */ + protected static String makeShortQuery(String query) { + query = query.replaceAll("(?i)set\\s+[\\w\\-.]+(\\s*)=(\\s*)[\\w\\-.]+(\\s*);", ""); + query = query.trim(); + return query.substring(0, (query.length() > 42)?42:query.length()); + } + + @Override + public SavedQuery update(SavedQuery newObject, String id) throws ItemNotFound { + SavedQuery savedQuery = super.update(newObject, id); + // Emptying short query so that in next read, this gets updated with proper value + // from the queryFile + emptyShortQueryField(savedQuery); + return savedQuery; + } + + @Override + public List readAll(FilteringStrategy filteringStrategy) { + List queries = super.readAll(filteringStrategy); + for(SavedQuery query : queries) { + String shortQuery = query.getShortQuery(); + if(shortQuery == null || shortQuery.isEmpty()) { + fillShortQueryField(query); + } + } + return queries; + } + + @Override + public void delete(Object resourceId) throws ItemNotFound { + super.delete(resourceId); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceProvider.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceProvider.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceProvider.java new file mode 100644 index 0000000..ba28060 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryResourceProvider.java @@ -0,0 +1,113 @@ +/** + * 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.*; +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 SavedQuery + */ +public class SavedQueryResourceProvider implements ResourceProvider { + @Inject + ViewContext context; + + protected final static Logger LOG = + LoggerFactory.getLogger(SavedQueryResourceProvider.class); + private SharedObjectsFactory sharedObjectsFactory; + + public SharedObjectsFactory getSharedObjectsFactory() { + if (sharedObjectsFactory == null) + sharedObjectsFactory = new SharedObjectsFactory(context); + return sharedObjectsFactory; + } + + protected synchronized SavedQueryResourceManager getResourceManager() { + return getSharedObjectsFactory().getSavedQueryResourceManager(); + } + + @Override + public SavedQuery 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 { + SavedQuery item = null; + try { + item = new SavedQuery(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 { + SavedQuery item = null; + try { + item = new SavedQuery(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/savedQueries/SavedQueryService.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryService.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryService.java new file mode 100644 index 0000000..7139ce8 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/savedQueries/SavedQueryService.java @@ -0,0 +1,267 @@ +/** + * 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.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.apache.ambari.view.utils.hdfs.HdfsApi; +import org.apache.ambari.view.utils.hdfs.HdfsUtil; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +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.StreamingOutput; +import javax.ws.rs.core.UriInfo; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.List; + +/** + * Servlet for queries + * API: + * GET /:id + * read SavedQuery + * POST / + * create new SavedQuery + * Required: title, queryFile + * GET / + * get all SavedQueries of current user + */ +public class SavedQueryService extends BaseService { + @Inject + ViewResourceHandler handler; + + protected SavedQueryResourceManager resourceManager = null; + protected final static Logger LOG = + LoggerFactory.getLogger(SavedQueryService.class); + + protected synchronized SavedQueryResourceManager getResourceManager() { + return getSharedObjectsFactory().getSavedQueryResourceManager(); + } + + protected void setResourceManager(SavedQueryResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + /** + * Get single item + */ + @GET + @Path("{queryId}") + @Produces(MediaType.APPLICATION_JSON) + public Response getOne(@PathParam("queryId") String queryId, + @QueryParam("op") String operation) { + try { + final SavedQuery savedQuery = getResourceManager().read(queryId); + if(operation.equals("download")) { + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, WebApplicationException { + Writer writer = new BufferedWriter(new OutputStreamWriter(os)); + try { + BufferedReader br=new BufferedReader(new InputStreamReader(getSharedObjectsFactory().getHdfsApi().open(savedQuery.getQueryFile()))); + String line; + line=br.readLine(); + while (line != null){ + writer.write(line+"\n"); + line = br.readLine(); + } + writer.flush(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + writer.close(); + } + } + }; + return Response.ok(stream). + type(MediaType.TEXT_PLAIN). + build(); + } + else { + JSONObject object = new JSONObject(); + object.put("savedQuery", savedQuery); + 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("{queryId}") + public Response delete(@PathParam("queryId") String queryId) { + try { + getResourceManager().delete(queryId); + 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 SavedQueries + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getList() { + try { + LOG.debug("Getting all SavedQuery"); + List allSavedQueries = getResourceManager().readAll( + new OnlyOwnersFilteringStrategy(this.context.getUsername())); //TODO: move strategy to PersonalCRUDRM + + JSONObject object = new JSONObject(); + object.put("savedQueries", allSavedQueries); + return Response.ok(object).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Update item + */ + @PUT + @Path("{queryId}") + @Consumes(MediaType.APPLICATION_JSON) + public Response update(SavedQueryRequest request, + @PathParam("queryId") String queryId) { + try { + getResourceManager().update(request.savedQuery, queryId); + 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 savedQuery + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response create(SavedQueryRequest request, @Context HttpServletResponse response, + @Context UriInfo ui) { + try { + getResourceManager().create(request.savedQuery); + + SavedQuery item = null; + + item = getResourceManager().read(request.savedQuery.getId()); + + response.setHeader("Location", + String.format("%s/%s", ui.getAbsolutePath().toString(), request.savedQuery.getId())); + + JSONObject object = new JSONObject(); + object.put("savedQuery", 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); + } + } + + /** + * Get default settings for query + */ + @GET + @Path("defaultSettings") + @Produces(MediaType.APPLICATION_JSON) + public Response getDefaultSettings() { + try { + String defaultsFile = context.getProperties().get("scripts.settings.defaults-file"); + HdfsApi hdfsApi = getSharedObjectsFactory().getHdfsApi(); + + String defaults = "{\"settings\": {}}"; + if (hdfsApi.exists(defaultsFile)) { + defaults = HdfsUtil.readFile(hdfsApi, defaultsFile); + } + return Response.ok(JSONValue.parse(defaults)).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Set default settings for query (overwrites if present) + */ + @POST + @Path("defaultSettings") + @Consumes(MediaType.APPLICATION_JSON) + public Response setDefaultSettings(JSONObject settings) { + try { + String defaultsFile = context.getProperties().get("scripts.settings.defaults-file"); + HdfsApi hdfsApi = getSharedObjectsFactory().getHdfsApi(); + + HdfsUtil.putStringToFile(hdfsApi, defaultsFile, + settings.toString()); + String defaults = HdfsUtil.readFile(hdfsApi, defaultsFile); + return Response.ok(JSONValue.parse(defaults)).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } + + /** + * Wrapper object for json mapping + */ + public static class SavedQueryRequest { + public SavedQuery savedQuery; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/Setting.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/Setting.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/Setting.java new file mode 100644 index 0000000..b9b0c3b --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/Setting.java @@ -0,0 +1,71 @@ +/** + * 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.settings; + +import org.apache.ambari.view.hive20.persistence.utils.PersonalResource; + +import java.io.Serializable; + +/** + * Entity to store the users settings + */ +public class Setting implements Serializable, PersonalResource { + + private String id; + private String owner; + private String key; + private String value; + + + @Override + public String getOwner() { + return owner; + } + + @Override + public void setOwner(String owner) { + this.owner = owner; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsResourceManager.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsResourceManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsResourceManager.java new file mode 100644 index 0000000..6e902db --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsResourceManager.java @@ -0,0 +1,97 @@ +/** + * 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.settings; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.persistence.utils.OnlyOwnersFilteringStrategy; +import org.apache.ambari.view.hive20.persistence.utils.StorageFactory; +import org.apache.ambari.view.hive20.resources.PersonalCRUDResourceManager; +import org.apache.ambari.view.hive20.utils.UniqueConstraintViolationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import java.util.List; + +/** + * + */ +public class SettingsResourceManager extends PersonalCRUDResourceManager { + + protected final Logger LOG = LoggerFactory.getLogger(getClass()); + + private final ViewContext context; + + @Inject + public SettingsResourceManager(ViewContext context) { + super(Setting.class, new StorageFactory(context), context); + this.context = context; + } + + public List getSettings() { + String username = context.getUsername(); + return super.readAll(new OnlyOwnersFilteringStrategy(username)); + } + + public void removeSetting(String id) throws ItemNotFound { + super.delete(id); + } + + public Setting create(Setting setting) { + List settings = getSettings(); + if (checkUniqueViolation(settings, setting)) { + LOG.error("Setting key: {} already exist for the user.", setting.getKey()); + throw new UniqueConstraintViolationException("Setting key: " + setting.getKey() + " already exists for the user"); + } + return super.create(setting); + } + + public Setting update(String id, Setting setting) throws ItemNotFound { + Setting current = read(id); + if(!current.getKey().equalsIgnoreCase(setting.getKey())) { + // If the settings key has changed + List settings = getSettings(); + if (checkUniqueViolation(settings, setting)) { + LOG.error("Setting key: {} already exist for the user.", setting.getKey()); + throw new UniqueConstraintViolationException("Setting key: " + setting.getKey() + " already exists for the user"); + } + } + return super.update(setting, id); + } + + /** + * @param settings List of all settings for the user + * @param setting new settings to be created + * @return true if the settings key is not unique + */ + private boolean checkUniqueViolation(List settings, final Setting setting) { + Optional settingOptional = FluentIterable.from(settings).filter(new Predicate() { + @Override + public boolean apply(@Nullable Setting input) { + return input.getKey().equalsIgnoreCase(setting.getKey()); + } + }).first(); + return settingOptional.isPresent(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsService.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsService.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsService.java new file mode 100644 index 0000000..240878b --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/settings/SettingsService.java @@ -0,0 +1,145 @@ +/** + * 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.settings; + +import org.apache.ambari.view.hive20.BaseService; +import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound; +import org.apache.ambari.view.hive20.utils.NotFoundFormattedException; +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.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +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; + +/** + * Service to support the API call for basic CRUD operations of User Setting + */ +public class SettingsService extends BaseService { + + protected final Logger LOG = + LoggerFactory.getLogger(getClass()); + + private final SettingsResourceManager resourceManager; + + @Inject + public SettingsService(SettingsResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + + /** + * Gets all the settings for the current user + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getAll() { + List settings = resourceManager.getSettings(); + JSONObject response = new JSONObject(); + response.put("settings", settings); + return Response.ok(response).build(); + } + + /** + * Adds a setting for the current user + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response addSetting(SettingRequest settingRequest, @Context HttpServletResponse response, @Context UriInfo uriInfo) { + Setting setting = resourceManager.create(settingRequest.getSetting()); + + response.setHeader("Location", + String.format("%s/%s", uriInfo.getAbsolutePath().toString(), setting.getId())); + + JSONObject op = new JSONObject(); + op.put("setting", setting); + return Response.ok(op).build(); + } + + /** + * Updates a setting for the current user + */ + @PUT + @Path("/{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateSetting(@PathParam("id") String id, SettingRequest settingRequest, @Context HttpServletResponse response, @Context UriInfo uriInfo) { + Setting setting = null; + try { + setting = resourceManager.update(id, settingRequest.getSetting()); + } catch (ItemNotFound itemNotFound) { + LOG.error("Error occurred while creating settings : ", itemNotFound); + throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound); + } + + response.setHeader("Location", + String.format("%s/%s", uriInfo.getAbsolutePath().toString(), setting.getId())); + + JSONObject op = new JSONObject(); + op.put("setting", setting); + return Response.ok(op).build(); + } + + /** + * Deletes a setting for the current user + */ + @DELETE + @Path("/{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response delete(@PathParam("id") String id) { + try { + resourceManager.removeSetting(id); + } catch (ItemNotFound itemNotFound) { + LOG.error("Error occurred while updating setting : ", itemNotFound); + throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound); + } + return Response.noContent().build(); + } + + /** + * Wrapper class for settings request + */ + public static class SettingRequest { + private Setting setting; + + public Setting getSetting() { + return setting; + } + + public void setSetting(Setting setting) { + this.setting = setting; + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/system/SystemService.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/system/SystemService.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/system/SystemService.java new file mode 100644 index 0000000..0afe43c --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/system/SystemService.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.system; + +import akka.actor.ActorRef; +import org.apache.ambari.view.hive20.BaseService; +import org.apache.ambari.view.hive20.ConnectionSystem; +import org.apache.ambari.view.hive20.actor.message.Ping; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +/** + * System services which are required for the working of the application + */ +public class SystemService extends BaseService { + + /** + * Clients should sent pings to the server at regular interval so that the system could keep alive stuffs or do + * cleanup work when the pings stops + * @return No content + */ + @POST + @Path("ping") + public Response ping() { + //TODO: Change this to EventBus implementation + ActorRef metaDataManager = ConnectionSystem.getInstance().getMetaDataManager(context); + metaDataManager.tell(new Ping(context.getUsername(), context.getInstanceName()), ActorRef.noSender()); + return Response.ok().status(Response.Status.NO_CONTENT).build(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDF.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDF.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDF.java new file mode 100644 index 0000000..362eb16 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDF.java @@ -0,0 +1,87 @@ +/** + * 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.udfs; + +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 UDF + */ +public class UDF implements Serializable, PersonalResource { + private String name; + private String classname; + private String fileResource; + + private String id; + private String owner; + + public UDF() {} + public UDF(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 getClassname() { + return classname; + } + + public void setClassname(String classname) { + this.classname = classname; + } + + public String getFileResource() { + return fileResource; + } + + public void setFileResource(String fileResource) { + this.fileResource = fileResource; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceManager.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceManager.java new file mode 100644 index 0000000..34d9c46 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceManager.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.udfs; + +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 udf objects + */ +public class UDFResourceManager extends PersonalCRUDResourceManager { + private final static Logger LOG = + LoggerFactory.getLogger(UDFResourceManager.class); + + /** + * Constructor + * @param context View Context instance + */ + public UDFResourceManager(IStorageFactory storageFactory, ViewContext context) { + super(UDF.class, storageFactory, context); + } + + @Override + public UDF read(Object id) throws ItemNotFound { + return super.read(id); + } + + @Override + public List readAll(FilteringStrategy filteringStrategy) { + return super.readAll(filteringStrategy); + } + + @Override + public UDF create(UDF object) { + return super.create(object); + } + + @Override + public void delete(Object resourceId) throws ItemNotFound { + super.delete(resourceId); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceProvider.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceProvider.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceProvider.java new file mode 100644 index 0000000..5735ea5 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFResourceProvider.java @@ -0,0 +1,111 @@ +/** + * 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.udfs; + +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 udf + */ +public class UDFResourceProvider implements ResourceProvider { + @Inject + ViewContext context; + + protected UDFResourceManager resourceManager = null; + protected final static Logger LOG = + LoggerFactory.getLogger(UDFResourceProvider.class); + + + protected synchronized UDFResourceManager getResourceManager() { + if (resourceManager == null) { + resourceManager = new UDFResourceManager(new SharedObjectsFactory(context), context); + } + return resourceManager; + } + + @Override + public UDF 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 { + UDF item = null; + try { + item = new UDF(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 { + UDF item = null; + try { + item = new UDF(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/udfs/UDFService.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFService.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFService.java new file mode 100644 index 0000000..5c8d2de --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/udfs/UDFService.java @@ -0,0 +1,193 @@ +/** + * 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.udfs; + +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.resources.resources.FileResourceResourceManager; +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 UDFs + * API: + * GET /:id + * read udf + * POST / + * create new udf + * GET / + * get all udf of current user + */ +public class UDFService extends BaseService { + @Inject + ViewResourceHandler handler; + + protected UDFResourceManager resourceManager = null; + protected FileResourceResourceManager fileResourceResourceManager = null; + protected final static Logger LOG = + LoggerFactory.getLogger(UDFService.class); + + protected synchronized UDFResourceManager getResourceManager() { + if (resourceManager == null) { + resourceManager = new UDFResourceManager(getSharedObjectsFactory(), context); + } + return resourceManager; + } + + protected synchronized FileResourceResourceManager getFileResourceResourceManager() { + if (fileResourceResourceManager == null) { + fileResourceResourceManager = new FileResourceResourceManager(getSharedObjectsFactory(), context); + } + return fileResourceResourceManager; + } + + /** + * Get single item + */ + @GET + @Path("{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response getOne(@PathParam("id") String id) { + try { + UDF udf = getResourceManager().read(id); + JSONObject object = new JSONObject(); + object.put("udf", udf); + 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 UDFs + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getList() { + try { + LOG.debug("Getting all udf"); + List items = getResourceManager().readAll( + new OnlyOwnersFilteringStrategy(this.context.getUsername())); //TODO: move strategy to PersonalCRUDRM + + JSONObject object = new JSONObject(); + object.put("udfs", 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(UDFRequest request, + @PathParam("id") String id) { + try { + if (request.udf.getFileResource() != null) + getFileResourceResourceManager().read(request.udf.getFileResource()); + getResourceManager().update(request.udf, 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 udf + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response create(UDFRequest request, @Context HttpServletResponse response, + @Context UriInfo ui) { + try { + if (request.udf.getFileResource() != null) + getFileResourceResourceManager().read(request.udf.getFileResource()); + getResourceManager().create(request.udf); + + UDF item = null; + + item = getResourceManager().read(request.udf.getId()); + + response.setHeader("Location", + String.format("%s/%s", ui.getAbsolutePath().toString(), request.udf.getId())); + + JSONObject object = new JSONObject(); + object.put("udf", 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 UDFRequest { + public UDF udf; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/CSVParams.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/CSVParams.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/CSVParams.java new file mode 100644 index 0000000..355ed6a --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/CSVParams.java @@ -0,0 +1,74 @@ +/** + * 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.hive.resources.uploads; + +import java.io.Serializable; + +public class CSVParams implements Serializable { + + public static final char DEFAULT_DELIMITER_CHAR = ','; + public static final char DEFAULT_ESCAPE_CHAR = '\\'; + public static final char DEFAULT_QUOTE_CHAR = '"'; + + private Character csvDelimiter; + private Character csvEscape; + private Character csvQuote; + + public CSVParams() { + } + + public CSVParams(Character csvDelimiter, Character csvQuote, Character csvEscape) { + this.csvDelimiter = csvDelimiter; + this.csvQuote = csvQuote; + this.csvEscape = csvEscape; + } + + public Character getCsvDelimiter() { + return csvDelimiter; + } + + public void setCsvDelimiter(Character csvDelimiter) { + this.csvDelimiter = csvDelimiter; + } + + public Character getCsvEscape() { + return csvEscape; + } + + public void setCsvEscape(Character csvEscape) { + this.csvEscape = csvEscape; + } + + public Character getCsvQuote() { + return csvQuote; + } + + public void setCsvQuote(Character csvQuote) { + this.csvQuote = csvQuote; + } + + @Override + public String toString() { + return "CSVParams{" + + "csvDelimiter='" + csvDelimiter + '\'' + + ", csvEscape='" + csvEscape + '\'' + + ", csvQuote='" + csvQuote + '\'' + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/ColumnDescriptionImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/ColumnDescriptionImpl.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/ColumnDescriptionImpl.java new file mode 100644 index 0000000..a5c0c3f --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/ColumnDescriptionImpl.java @@ -0,0 +1,119 @@ +/** + * 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.uploads; + +import org.apache.ambari.view.hive20.client.ColumnDescription; + +import java.io.Serializable; + +/** + * implementation of ColumnDescription which also includes scale and precision. + */ +public class ColumnDescriptionImpl implements ColumnDescription, Serializable { + private String name; + private String type; + private int position; + /** + * can be null + */ + private Integer precision; + /** + * can be null + */ + private Integer scale; + + public ColumnDescriptionImpl() { + } + + public ColumnDescriptionImpl(String name, String type, int position) { + this.name = name; + this.type = type; + this.position = position; + } + + public ColumnDescriptionImpl(String name, String type, int position, int precision) { + this.name = name; + this.type = type; + this.position = position; + this.precision = precision; + } + + public ColumnDescriptionImpl(String name, String type, int position, int precision, int scale) { + this.name = name; + this.type = type; + this.position = position; + this.precision = precision; + this.scale = scale; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getType() { + return type; + } + + @Override + public int getPosition() { + return this.position; + } + + public Integer getPrecision() { + return precision; + } + + public Integer getScale() { + return scale; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ColumnDescriptionImpl that = (ColumnDescriptionImpl) o; + + if (position != that.position) return false; + if (!name.equals(that.name)) return false; + return type.equals(that.type); + + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + type.hashCode(); + result = 31 * result + position; + return result; + } + + @Override + public String toString() { + return new StringBuilder().append("ColumnDescriptionImpl[") + .append("name : ").append(name) + .append(", type : " + type) + .append(", position : " + position) + .append(", precision : " + precision) + .append(", scale : " + scale) + .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/uploads/HiveFileType.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/HiveFileType.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/HiveFileType.java new file mode 100644 index 0000000..872bc9c --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/HiveFileType.java @@ -0,0 +1,30 @@ + +/** + * 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.uploads; + +public enum HiveFileType { + SEQUENCEFILE, + TEXTFILE, + RCFILE, + ORC, + PARQUET, + AVRO, + INPUTFORMAT; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableDataReader.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableDataReader.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableDataReader.java new file mode 100644 index 0000000..ee148b8 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableDataReader.java @@ -0,0 +1,111 @@ +/** + * 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.uploads; + +import com.opencsv.CSVWriter; +import org.apache.ambari.view.hive20.client.ColumnDescription; +import org.apache.ambari.view.hive20.client.Row; +import org.apache.commons.codec.binary.Hex; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Iterator; +import java.util.List; + +/** + * Takes row iterator as input. + * iterate over rows and creates a CSV formated stream separating rows by endline "\n" + * Note : column values should not contain "\n". + */ +public class TableDataReader extends Reader { + + private static final int CAPACITY = 1024; + private final List header; + private StringReader stringReader = new StringReader(""); + + private Iterator iterator; + private boolean encode = false; + public static final char CSV_DELIMITER = '\001'; + + public TableDataReader(Iterator rowIterator, List header, boolean encode) { + this.iterator = rowIterator; + this.encode = encode; + this.header = header; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + + int totalLen = len; + int count = 0; + do { + int n = stringReader.read(cbuf, off, len); + + if (n != -1) { + // n were read + len = len - n; // len more to be read + off = off + n; // off now shifted to n more + count += n; + } + + if (count == totalLen) return count; // all totalLen characters were read + + if (iterator.hasNext()) { // keep reading as long as we keep getting rows + StringWriter stringWriter = new StringWriter(CAPACITY); + CSVWriter csvPrinter = new CSVWriter(stringWriter,CSV_DELIMITER); + Row row = iterator.next(); + // encode values so that \n and \r are overridden + Object[] columnValues = row.getRow(); + String[] columns = new String[columnValues.length]; + + for(int i = 0; i < columnValues.length; i++){ + String type = header.get(i).getType(); + if(this.encode && + ( + ColumnDescription.DataTypes.STRING.toString().equals(type) + || ColumnDescription.DataTypes.VARCHAR.toString().equals(type) + || ColumnDescription.DataTypes.CHAR.toString().equals(type) + ) + ){ + columns[i] = Hex.encodeHexString(((String)columnValues[i]).getBytes()); //default charset + }else { + columns[i] = (String) columnValues[i]; + } + } + + csvPrinter.writeNext(columns,false); + stringReader.close(); // close the old string reader + stringReader = new StringReader(stringWriter.getBuffer().toString()); + csvPrinter.close(); + stringWriter.close(); + } else { + return count == 0 ? -1 : count; + } + } while (count < totalLen); + + return count; + } + + @Override + public void close() throws IOException { + + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableInput.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableInput.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableInput.java new file mode 100644 index 0000000..4f15c57 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/TableInput.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.view.hive20.resources.uploads; + +import org.apache.ambari.view.hive20.resources.uploads.query.TableInfo; + +/** + * used as input in REST call + */ +class TableInput extends TableInfo { + public Boolean isFirstRowHeader = Boolean.FALSE; + + public TableInput() { + } + + public Boolean getIsFirstRowHeader() { + return isFirstRowHeader; + } + + public void setIsFirstRowHeader(Boolean isFirstRowHeader) { + this.isFirstRowHeader = isFirstRowHeader; + } + + public void validate(){ + if( null == this.getHiveFileType()){ + throw new IllegalArgumentException("fileType parameter cannot be null."); + } + if( null == this.getTableName()){ + throw new IllegalArgumentException("tableName parameter cannot be null."); + } + if( null == this.getDatabaseName()){ + throw new IllegalArgumentException("databaseName parameter cannot be null."); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/853a1ce7/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/UploadFromHdfsInput.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/UploadFromHdfsInput.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/UploadFromHdfsInput.java new file mode 100644 index 0000000..c755c02 --- /dev/null +++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/uploads/UploadFromHdfsInput.java @@ -0,0 +1,130 @@ +/** + * 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.uploads; + +import java.io.Serializable; +import java.util.List; + +public class UploadFromHdfsInput implements Serializable{ + private Boolean isFirstRowHeader = Boolean.FALSE; + private String inputFileType; + private String hdfsPath; + private String tableName; + private String databaseName; + private List header; + private boolean containsEndlines; + + private String csvDelimiter; + private String csvEscape; + private String csvQuote; + + public UploadFromHdfsInput() { + } + + public String getCsvDelimiter() { + return csvDelimiter; + } + + public List getHeader() { + return header; + } + + public void setHeader(List header) { + this.header = header; + } + + public boolean isContainsEndlines() { + return containsEndlines; + } + + public void setContainsEndlines(boolean containsEndlines) { + this.containsEndlines = containsEndlines; + } + + public void setCsvDelimiter(String csvDelimiter) { + this.csvDelimiter = csvDelimiter; + } + + public String getCsvEscape() { + return csvEscape; + } + + public void setCsvEscape(String csvEscape) { + this.csvEscape = csvEscape; + } + + public String getCsvQuote() { + return csvQuote; + } + + public void setCsvQuote(String csvQuote) { + this.csvQuote = csvQuote; + } + + public Boolean getIsFirstRowHeader() { + return isFirstRowHeader; + } + + public void setIsFirstRowHeader(Boolean firstRowHeader) { + isFirstRowHeader = firstRowHeader; + } + + public String getInputFileType() { + return inputFileType; + } + + public void setInputFileType(String inputFileType) { + this.inputFileType = inputFileType; + } + + public String getHdfsPath() { + return hdfsPath; + } + + public void setHdfsPath(String hdfsPath) { + this.hdfsPath = hdfsPath; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public String getDatabaseName() { + return databaseName; + } + + public void setDatabaseName(String databaseName) { + this.databaseName = databaseName; + } + + @Override + public String toString() { + return new StringBuilder("UploadFromHdfsInput{" ) + .append("isFirstRowHeader=").append( isFirstRowHeader ) + .append(", inputFileType='" ).append(inputFileType) + .append(", hdfsPath='").append(hdfsPath) + .append(", tableName='").append( tableName ) + .append(", databaseName='").append(databaseName ) + .append('}').toString(); + } +}