diff --git a/client/src/main/java/org/apache/sqoop/client/request/ConnectorRequest.java b/client/src/main/java/org/apache/sqoop/client/request/ConnectorRequest.java new file mode 100644 index 00000000..28667000 --- /dev/null +++ b/client/src/main/java/org/apache/sqoop/client/request/ConnectorRequest.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.sqoop.client.request; + +import org.apache.sqoop.json.ConnectorBean; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +public class ConnectorRequest extends Request +{ + public ConnectorBean doGet(String serverUrl, String cid) { + String response = null; + if (cid == null) { + response = super.get(serverUrl + "v1/connector/all"); + } else { + response = super.get(serverUrl + "v1/connector/" + cid); + } + JSONObject jsonObject = (JSONObject)JSONValue.parse(response); + + ConnectorBean connectorBean = new ConnectorBean(); + connectorBean.restore(jsonObject); + + return connectorBean; + } +} \ No newline at end of file diff --git a/client/src/main/java/org/apache/sqoop/client/request/VersionRequest.java b/client/src/main/java/org/apache/sqoop/client/request/VersionRequest.java index f566349d..511878c7 100644 --- a/client/src/main/java/org/apache/sqoop/client/request/VersionRequest.java +++ b/client/src/main/java/org/apache/sqoop/client/request/VersionRequest.java @@ -23,8 +23,8 @@ public class VersionRequest extends Request { - public VersionBean version(String url) { - String response = get(url + "version"); + public VersionBean doGet(String serverUrl) { + String response = super.get(serverUrl + "version"); JSONObject jsonObject = (JSONObject)JSONValue.parse(response); VersionBean versionBean = new VersionBean(); diff --git a/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java b/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java index a1e34adc..c5b72581 100644 --- a/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java +++ b/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java @@ -27,6 +27,7 @@ public class ShowCommand extends SqoopCommand { private ShowServerFunction serverFunction; private ShowVersionFunction versionFunction; + private ShowConnectorFunction connectorFunction; protected ShowCommand(Shell shell) { super(shell, "show", "\\sh", @@ -57,7 +58,10 @@ public Object execute(List args) { return versionFunction.execute(args); } else if (func.equals("connector")) { - return null; + if (connectorFunction == null) { + connectorFunction = new ShowConnectorFunction(io); + } + return connectorFunction.execute(args); } else if (func.equals("connection")) { return null; @@ -70,4 +74,4 @@ public Object execute(List args) { throw new SqoopException(ClientError.CLIENT_0002, msg); } } -} +} \ No newline at end of file diff --git a/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java b/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java new file mode 100644 index 00000000..2d80d6f0 --- /dev/null +++ b/client/src/main/java/org/apache/sqoop/client/shell/ShowConnectorFunction.java @@ -0,0 +1,114 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sqoop.client.shell; + +import java.io.PrintWriter; +import java.util.List; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.OptionBuilder; +import org.apache.sqoop.client.core.Environment; +import org.apache.sqoop.client.request.ConnectorRequest; +import org.apache.sqoop.json.ConnectorBean; +import org.codehaus.groovy.tools.shell.IO; + +@SuppressWarnings("serial") +public class ShowConnectorFunction extends SqoopFunction +{ + public static final String ALL = "all"; + public static final String CID = "cid"; + + private IO io; + private ConnectorRequest conntectorRequest; + + @SuppressWarnings("static-access") + protected ShowConnectorFunction(IO io) { + this.io = io; + + this.addOption(OptionBuilder + .withDescription("Display all connectors") + .withLongOpt(ALL) + .create(ALL.charAt(0))); + this.addOption(OptionBuilder.hasArg().withArgName("cid") + .withDescription( "Display the connector with cid" ) + .withLongOpt(CID) + .create(CID.charAt(0))); + } + + public void printHelp(PrintWriter out) { + out.println("Usage: show connector"); + super.printHelp(out); + } + + public Object execute(List args) { + if (args.size() == 1) { + printHelp(io.out); + io.out.println(); + return null; + } + + CommandLine line = parseOptions(this, 1, args); + if (line.hasOption(ALL)) { + showConnector(null); + + } else if (line.hasOption(CID)) { + showConnector(line.getOptionValue(CID)); + } + + return null; + } + + private void showConnector(String cid) { + if (conntectorRequest == null) { + conntectorRequest = new ConnectorRequest(); + } + ConnectorBean connectorBean = + conntectorRequest.doGet(Environment.getServerUrl(), cid); + long[] ids = connectorBean.getIds(); + String[] names = connectorBean.getNames(); + String[] classes = connectorBean.getClasses(); + + if (cid == null) { + io.out.println("@|bold Metadata for all connectors:|@"); + int size = ids.length; + for (int i = 0; i < size; i++) { + io.out.print("Connector "); + io.out.print(i+1); + io.out.println(":"); + + io.out.print(" Id: "); + io.out.println(ids[i]); + io.out.print(" Name: "); + io.out.println(names[i]); + io.out.print(" Class: "); + io.out.println(classes[i]); + } + + } else { + io.out.println("@|bold Metadata for the connector:|@"); + io.out.print(" Id: "); + io.out.println(ids[0]); + io.out.print(" Name: "); + io.out.println(names[0]); + io.out.print(" Class: "); + io.out.println(classes[0]); + } + + io.out.println(); + } +} \ No newline at end of file diff --git a/client/src/main/java/org/apache/sqoop/client/shell/ShowVersionFunction.java b/client/src/main/java/org/apache/sqoop/client/shell/ShowVersionFunction.java index 85c2a986..9e8c607c 100644 --- a/client/src/main/java/org/apache/sqoop/client/shell/ShowVersionFunction.java +++ b/client/src/main/java/org/apache/sqoop/client/shell/ShowVersionFunction.java @@ -101,7 +101,7 @@ private void showVersion(boolean server, boolean client, boolean protocol) { versionRequest = new VersionRequest(); } VersionBean versionBean = - versionRequest.version(Environment.getServerUrl()); + versionRequest.doGet(Environment.getServerUrl()); if (server) { io.out.println("@|bold Server version:|@"); diff --git a/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java b/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java new file mode 100644 index 00000000..4ecdf305 --- /dev/null +++ b/common/src/main/java/org/apache/sqoop/json/ConnectorBean.java @@ -0,0 +1,103 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sqoop.json; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +public class ConnectorBean implements JsonBean { + + public static final String IDS = "ids"; + public static final String NAMES = "names"; + public static final String CLASSES = "classes"; + + private long[] ids; + private String[] names; + private String[] classes; + + // for "extract" + public ConnectorBean(long[] ids, String[] names, String[] classes) { + this.ids = new long[ids.length]; + System.arraycopy(ids, 0, this.ids, 0, ids.length); + this.names = new String[names.length]; + System.arraycopy(names, 0, this.names, 0, names.length); + this.classes = new String[classes.length]; + System.arraycopy(classes, 0, this.classes, 0, classes.length); + } + + // for "restore" + public ConnectorBean() { + } + + @SuppressWarnings("unchecked") + @Override + public JSONObject extract() { + JSONObject result = new JSONObject(); + JSONArray idsArray = new JSONArray(); + for (long id : ids) { + idsArray.add(id); + } + result.put(IDS, idsArray); + JSONArray namesArray = new JSONArray(); + for (String name : names) { + namesArray.add(name); + } + result.put(NAMES, namesArray); + JSONArray classesArray = new JSONArray(); + for (String clz : classes) { + classesArray.add(clz); + } + result.put(CLASSES, classesArray); + return result; + } + + @Override + public void restore(JSONObject jsonObject) { + JSONArray idsArray = (JSONArray) jsonObject.get(IDS); + int idsSize = idsArray.size(); + ids = new long[idsSize]; + for (int i = 0; i nameMap = new HashMap(); + + // key: connector name, value: connector handler private static Map handlerMap = new HashMap(); + public static ConnectorHandler[] getHandlers() { + return handlerMap.values().toArray(new ConnectorHandler[]{}); + } + + public static ConnectorHandler getHandler(long connectorId) { + return handlerMap.get(nameMap.get(connectorId)); + } + public static synchronized void initialize() { if (LOG.isTraceEnabled()) { LOG.trace("Begin connector manager initialization"); @@ -116,6 +128,13 @@ private static synchronized void registerConnectors() { + registeredMetadata); } } + + long connectorId = handler.getMetadata().getPersistenceId(); + String connectorName = handler.getUniqueName(); + if (connectorId == -1) { + throw new SqoopException(ConnectorError.CONN_0010, connectorName); + } + nameMap.put(connectorId, connectorName); } rtx.commit(); } catch (Exception ex) { diff --git a/server/src/main/java/org/apache/sqoop/handler/ConnectorRequestHandler.java b/server/src/main/java/org/apache/sqoop/handler/ConnectorRequestHandler.java new file mode 100644 index 00000000..74c1e04d --- /dev/null +++ b/server/src/main/java/org/apache/sqoop/handler/ConnectorRequestHandler.java @@ -0,0 +1,81 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sqoop.handler; + +import org.apache.log4j.Logger; +import org.apache.sqoop.common.SqoopException; +import org.apache.sqoop.connector.ConnectorHandler; +import org.apache.sqoop.connector.ConnectorManager; +import org.apache.sqoop.json.JsonBean; +import org.apache.sqoop.json.ConnectorBean; +import org.apache.sqoop.server.RequestContext; +import org.apache.sqoop.server.RequestHandler; + +public class ConnectorRequestHandler implements RequestHandler { + + private static final Logger LOG = + Logger.getLogger(ConnectorRequestHandler.class); + + /** The API version supported by this server */ + public static final String PROTOCOL_V1 = "1"; + + + private ConnectorBean connectors; + + public ConnectorRequestHandler() { + LOG.info("ConnectorRequestHandler initialized"); + } + + + @Override + public JsonBean handleEvent(RequestContext ctx) throws SqoopException { + ConnectorBean connectorBean; + + String uri = ctx.getRequest().getRequestURI(); + int slash = uri.lastIndexOf("/"); + String cid = uri.substring(slash + 1); + LOG.info("ConnectorRequestHandler handles cid: " + cid); + if (cid.equals("all")) { + // display all connectors + if (connectors == null) { + ConnectorHandler[] handlers = ConnectorManager.getHandlers(); + long[] ids = new long[handlers.length]; + String[] names = new String[handlers.length]; + String[] classes = new String[handlers.length]; + for (int i = 0; i < handlers.length; i++) { + ids[i] = handlers[i].getMetadata().getPersistenceId(); + names[i] = handlers[i].getUniqueName(); + classes[i] = handlers[i].getConnectorClassName(); + } + connectors = new ConnectorBean(ids, names, classes); + } + connectorBean = connectors; + + } else { + // display one connector + ConnectorHandler handler = + ConnectorManager.getHandler(Long.parseLong(cid)); + long[] ids = new long[] { handler.getMetadata().getPersistenceId() }; + String[] names = new String[] { handler.getUniqueName() }; + String[] classes = new String[] { handler.getConnectorClassName() }; + connectorBean = new ConnectorBean(ids, names, classes); + } + + return connectorBean; + } +} diff --git a/server/src/main/java/org/apache/sqoop/server/v1/ConnectorServlet.java b/server/src/main/java/org/apache/sqoop/server/v1/ConnectorServlet.java index 07a86ae2..d24ac10b 100644 --- a/server/src/main/java/org/apache/sqoop/server/v1/ConnectorServlet.java +++ b/server/src/main/java/org/apache/sqoop/server/v1/ConnectorServlet.java @@ -17,8 +17,10 @@ */ package org.apache.sqoop.server.v1; +import org.apache.sqoop.handler.ConnectorRequestHandler; import org.apache.sqoop.json.JsonBean; import org.apache.sqoop.server.RequestContext; +import org.apache.sqoop.server.RequestHandler; import org.apache.sqoop.server.SqoopProtocolServlet; /** @@ -28,9 +30,14 @@ @SuppressWarnings("serial") public class ConnectorServlet extends SqoopProtocolServlet { + private RequestHandler connectorRequestHandler; + + public ConnectorServlet() { + connectorRequestHandler = new ConnectorRequestHandler(); + } + @Override protected JsonBean handleGetRequest(RequestContext ctx) throws Exception { - // TODO Auto-generated method stub - return super.handleGetRequest(ctx); + return connectorRequestHandler.handleEvent(ctx); } } diff --git a/server/src/main/webapp/WEB-INF/web.xml b/server/src/main/webapp/WEB-INF/web.xml index 63abe60a..6acf037b 100644 --- a/server/src/main/webapp/WEB-INF/web.xml +++ b/server/src/main/webapp/WEB-INF/web.xml @@ -46,7 +46,7 @@ limitations under the License. v1.ConnectorServlet - /v1/connector + /v1/connector/*