Skip to content

Commit

Permalink
Merge pull request #2 from mastern2k3/master
Browse files Browse the repository at this point in the history
initial
  • Loading branch information
ronenquali committed Feb 24, 2016
2 parents 9009a11 + 231f4a4 commit c55a4b4
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.idea/
out/
*.jar
13 changes: 13 additions & 0 deletions intelli-qs-plugin.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
36 changes: 36 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<idea-plugin version="2">
<id>com.qualisystems.pythonDriverPlugin</id>
<name>Quali Python Driver Uploader</name>
<version>1.0</version>
<vendor email="support@qualisystems.com" url="http://www.qualisystems.com/">QualiSystems</vendor>

<description><![CDATA[
Publishes the driver project on a Quali server.<br>
Make sure you have a `deployment.xml` file present in your project root.
]]></description>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="141.0"/>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<depends>com.intellij.modules.lang</depends>

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
</extensions>

<actions>
<!-- Add your actions here -->
<action id="QualiPublishDriverAction"
class="com.qualisystems.pythonDriverPlugin.QualiPublishDriverAction"
text="Publish Python Driver on CloudShell"
description="Publishes the driver project on CloudShell"
icon="/qs-icon.png">
<add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
<add-to-group group-id="RunnerActions" anchor="first"/>
</action>
</actions>

</idea-plugin>
Binary file added resources/qs-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.qualisystems.pythonDriverPlugin;

import org.apache.commons.lang.ArrayUtils;

import java.util.Properties;

public class DriverPublisherSettings {

String serverRootAddress;
int port;
String driverUniqueName;
String username;
String password;
String domain;
String[] fileFilters;

private static final String[] DefaultFileFilters = new String[] { ".idea", "deployment", "deployment.xml" };

public static DriverPublisherSettings fromProperties(Properties deploymentProperties) throws IllegalArgumentException {

if (!deploymentProperties.containsKey("driverUniqueName"))
throw new IllegalArgumentException("Missing `driverUniqueName` key in project's deployment.xml");

if (!deploymentProperties.containsKey("serverRootAddress"))
throw new IllegalArgumentException("Missing `serverRootAddress` key in project's deployment.xml");

DriverPublisherSettings settings = new DriverPublisherSettings();

settings.serverRootAddress = deploymentProperties.getProperty("serverRootAddress");
settings.port = Integer.parseInt(deploymentProperties.getProperty("port", "8029"));
settings.driverUniqueName = deploymentProperties.getProperty("driverUniqueName");
settings.username = deploymentProperties.getProperty("username", "admin");
settings.password = deploymentProperties.getProperty("password", "admin");
settings.domain = deploymentProperties.getProperty("domain", "Global");

String fileFiltersValue = deploymentProperties.getProperty("fileFilters", "");

String[] extraFilters = fileFiltersValue.isEmpty() ? new String[0] : fileFiltersValue.split(";");

settings.fileFilters = (String[])ArrayUtils.addAll(DefaultFileFilters, extraFilters);

return settings;
}
}
120 changes: 120 additions & 0 deletions src/com/qualisystems/pythonDriverPlugin/QualiPublishDriverAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.qualisystems.pythonDriverPlugin;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NotNull;

import java.io.*;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;

public class QualiPublishDriverAction extends AnAction {

public static final String DeploymentSettingsFileName = "deployment.xml";

@Override
public void actionPerformed(AnActionEvent anActionEvent) {

final Project project = anActionEvent.getData(CommonDataKeys.PROJECT);

if (project == null) return;

final File deploymentSettingsFile = new File(project.getBasePath(), DeploymentSettingsFileName);

if (!deploymentSettingsFile.exists()) {

Messages.showErrorDialog(
project,
"Could not find deployment.xml in the project folder, cannot upload driver.",
"Missing Deployment Configuration File");

return;
}

ProgressManager.getInstance().run(new Task.Backgroundable(project, "Publishing Python Driver on CloudShell") {

public Exception _exception;
public DriverPublisherSettings _settings;

@Override
public void onSuccess() {

if (_exception != null) {

_exception.printStackTrace();

if (_exception instanceof UnknownHostException)
Messages.showErrorDialog(
project,
"Failed uploading new driver file:\n Unknown Host",
"Publishing Python Driver on CloudShell");
else
Messages.showErrorDialog(
project,
"Failed uploading new driver file:\n" + _exception.toString(),
"Publishing Python Driver on CloudShell");

return;
}

if (_settings == null) return;

Messages.showInfoMessage(
project,
String.format("Successfully uploaded new driver file for driver `%s`", _settings.driverUniqueName),
"Publishing Python Driver on CloudShell");
}

@Override
public void run(@NotNull ProgressIndicator progressIndicator) {

try {

_settings = getDeploymentSettingsFromFile(deploymentSettingsFile);

ResourceManagementService resourceManagementService =
ResourceManagementService.OpenConnection(_settings.serverRootAddress, _settings.port, _settings.username, _settings.password, _settings.domain);

File zippedProjectFile = zipProjectFolder(project.getBasePath(), _settings);

resourceManagementService.updateDriver(_settings.driverUniqueName, zippedProjectFile);

} catch (Exception e) {

_exception = e;
}
}
});
}

private File zipProjectFolder(String directory, DriverPublisherSettings settings) throws IOException {

ZipHelper zipHelper = new ZipHelper(settings.fileFilters);

Path deploymentFilePath = Paths.get(directory, "deployment", settings.driverUniqueName + ".zip");

zipHelper.zipDir(directory, deploymentFilePath.toString());

return deploymentFilePath.toFile();
}

private DriverPublisherSettings getDeploymentSettingsFromFile(File deploymentSettingsFile) throws IOException {

Properties properties = new Properties();

properties.loadFromXML(Files.newInputStream(deploymentSettingsFile.toPath()));

DriverPublisherSettings settings = DriverPublisherSettings.fromProperties(properties);

return settings;
}
}
133 changes: 133 additions & 0 deletions src/com/qualisystems/pythonDriverPlugin/ResourceManagementService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.qualisystems.pythonDriverPlugin;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.DataOutputStream;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.InetAddress;
import java.nio.file.Files;
import java.util.Base64;

public class ResourceManagementService {

private static final String TargetServerURLFormat = "http://%s:%s/%s";

private static final String LoginEndpointPath = "ResourceManagerApiService/Logon";
private static final String LogonRequestFormat =
"<Logon>\n" +
"<username>%s</username>\n" +
"<password>%s</password>\n" +
"<domainName>%s</domainName>\n" +
"</Logon>";

private static final String UpdateDriverEndpointPath = "ResourceManagerApiService/UpdateDriver";
private static final String UpdateDriverRequestFormat =
"<UpdateDriver>\n" +
"<driverName>%s</driverName>\n" +
"<driverFile>%s</driverFile>\n" +
"<driverFileName>%s</driverFileName>\n" +
"</UpdateDriver>";

public static ResourceManagementService OpenConnection(String serverAddress, int port, String username, String password, String domain) throws Exception {

ResourceManagementService resourceManagementService = new ResourceManagementService(serverAddress, port);

resourceManagementService.login(username, password, domain);

return resourceManagementService;
}

private void login(String username, String password, String domain) throws Exception {

String serverURL = String.format(TargetServerURLFormat, _serverAddress, _port, LoginEndpointPath);

Document doc = sendMessage(new URL(serverURL), String.format(LogonRequestFormat, username, password, domain));

NodeList tokenElement = doc.getElementsByTagName("Token");

if (tokenElement.getLength() != 1)
throw new Exception("No token element in logon response");

_authToken = tokenElement.item(0).getAttributes().getNamedItem("Token").getTextContent();
}

public void updateDriver(String driverName, File newDriverFile) throws Exception {

String base64DriverFile =
Base64.getEncoder().encodeToString(Files.readAllBytes(newDriverFile.toPath()));

String serverURL = String.format(TargetServerURLFormat, _serverAddress, _port, UpdateDriverEndpointPath);

sendMessage(new URL(serverURL), String.format(UpdateDriverRequestFormat, driverName, base64DriverFile, newDriverFile.getName()));
}

private Document sendMessage(URL requestURL, String message) throws Exception {

HttpURLConnection con = (HttpURLConnection) requestURL.openConnection();

con.setRequestMethod("POST");
con.setRequestProperty("DateTimeFormat", "MM/dd/yyyy HH:mm");
con.setRequestProperty("ClientTimeZoneId", "UTC");
con.setRequestProperty("Content-Type", "text/xml");
con.setRequestProperty("Accept", "*/*");
con.setRequestProperty("Authorization", String.format("MachineName=%s;Token=%s", _hostname, _authToken));
con.setRequestProperty("Host", _serverAddress + ":" + Integer.toString(_port));

con.setDoOutput(true);

DataOutputStream wr = new DataOutputStream(con.getOutputStream());

wr.writeBytes(message);

wr.flush();
wr.close();

int responseCode = con.getResponseCode();

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

Document responseXml = builder.parse(con.getInputStream());

NodeList elements = responseXml.getElementsByTagName("Error");

if (elements.getLength() > 0)
throw new Exception(String.format("API Message: %s", elements.item(0).getTextContent()));

if (!isSuccessResponseCode(responseCode))
throw new Exception("Error making request, Response code: " + responseCode);

return responseXml;
}

private boolean isSuccessResponseCode(int responseCode) {
return responseCode >= 200 && responseCode < 300;
}

private final String _serverAddress;
private final String _hostname;
private final int _port;

private String _authToken;

private ResourceManagementService(String serverAddress, int port) {

_serverAddress = serverAddress;
_port = port;

String hostname;

try {
hostname = InetAddress.getLocalHost().getHostName();
} catch (Exception ex) {
hostname = "localhost";
}

_hostname = hostname;
}
}
Loading

0 comments on commit c55a4b4

Please sign in to comment.