/*******************************************************************************
* Copyright (c) May 18, 2011 Zend Technologies Ltd.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.zend.sdkcli.internal.commands;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.zend.sdkcli.internal.options.Option;
import org.zend.sdklib.internal.target.ZendTarget;
import org.zend.sdklib.manager.TargetException;
import org.zend.sdklib.manager.TargetsManager;
import org.zend.sdklib.target.IZendTarget;
import org.zend.sdklib.target.LicenseExpiredException;
import org.zend.webapi.core.WebApiException;
import org.zend.webapi.core.connection.data.values.ServerType;
import org.zend.webapi.core.connection.data.values.WebApiVersion;
import org.zend.webapi.core.connection.response.ResponseCode;
import org.zend.webapi.internal.core.connection.exception.UnexpectedResponseCode;
import org.zend.webapi.internal.core.connection.exception.WebApiCommunicationError;
/**
* Creating a new target
*
* @author Roy, 2011
*/
public class AddTargetCommand extends TargetAwareCommand {
private static final int[] possiblePorts = new int[] { 10081, 10082, 10088 };
// properties file keys
private static final String PROP_SECRETKEY = "secretkey";
private static final String PROP_KEY = "key";
// options
private static final String ID = "t";
private static final String KEY = "k";
private static final String SECRETKEY = "s";
private static final String HOST = "h";
private static final String PROPERTIES = "p";
private Properties props;
@Option(opt = ID, required = false, description = "id of the new target", argName = "id")
public String getId() {
return getValue(ID);
}
@Option(opt = KEY, required = false, description = "API key used by the new target", argName = PROP_KEY)
public String getKey() {
Properties p = getProperties();
if (p != null) {
return p.getProperty(PROP_KEY);
}
return getValue(KEY);
}
@Option(opt = SECRETKEY, required = false, description = "API secret key used by the new target", argName = "secret-key")
public String getSecretKey() {
Properties p = getProperties();
if (p != null) {
return p.getProperty(PROP_SECRETKEY);
}
return getValue(SECRETKEY);
}
@Option(opt = HOST, required = false, description = "Host URL of the new target", argName = "host")
public String getHost() {
return getValue(HOST);
}
@Option(opt = PROPERTIES, required = false, description = "Properties file specifies 'key' and 'secretkey' values", argName = "path-to-file")
public File getPropertiesFile() {
final String filename = getValue(PROPERTIES);
if (filename == null || filename.length() == 0) {
return null;
}
final File file = new File(filename);
return file;
}
@Override
public boolean doExecute() {
String targetId = getId();
TargetsManager targetManager = getTargetManager();
List<IZendTarget> targets = new ArrayList<IZendTarget>();
String key = getKey();
String secretKey = getSecretKey();
String host = getHost();
File props = getPropertiesFile();
if (host == null
|| ((key == null || secretKey == null) && (props == null || !props
.exists()))) {
getLogger()
.error("To create target it is required to provide hostname, key and secret key. "
+ "They can be provided through a properties file or as command's arguments.");
return false;
}
if (targetId == null) {
targetId = targetManager.createUniqueId(null);
}
try {
targets.add(new ZendTarget(targetId, new URL(host), key,
secretKey));
} catch (MalformedURLException e) {
getLogger().error(
MessageFormat.format(
"Cannot add target {0}. Invalid host value.",
getId()));
}
List<IZendTarget> toRemove = new ArrayList<IZendTarget>();
for (IZendTarget t : targets) {
IZendTarget target = null;
try {
target = testConnectAndDetectPort(t);
IZendTarget[] existingTargets = targetManager.getTargets();
for (IZendTarget existingTarget : existingTargets) {
if (existingTarget.getHost().toString()
.equals(target.getHost().toString())) {
getLogger()
.error(MessageFormat
.format("Cannot add target with {0} host. Target with such host already exists.",
target.getHost().toString()));
continue;
}
}
if (target != null) {
targetManager.add(target, true);
getLogger()
.info(MessageFormat
.format("Target {0} was added successfully, with id {1}",
t.getHost().toString(), t.getId()));
} else {
toRemove.add(t);
}
} catch (LicenseExpiredException e) {
getLogger()
.error(MessageFormat
.format("Cannot add target {0}. Check if license has not exipred.",
getId()));
} catch (WebApiException e) {
getLogger().error(
MessageFormat.format(
"Cannot add target {0}. " + e.getMessage(),
getId()));
} catch (TargetException e) {
getLogger().error(
MessageFormat.format(
"Cannot add target {0}. " + e.getMessage(),
getId()));
}
}
for (IZendTarget t : toRemove) {
targets.remove(t);
}
if (targets.size() == 0) {
return false;
}
return true;
}
public IZendTarget testTargetConnection(IZendTarget target)
throws WebApiException, LicenseExpiredException {
try {
if (target.connect(WebApiVersion.V1_3, ServerType.ZEND_SERVER)) {
return target;
}
} catch (WebApiCommunicationError e) {
throw e;
} catch (UnexpectedResponseCode e) {
ResponseCode code = e.getResponseCode();
switch (code) {
case INTERNAL_SERVER_ERROR:
case AUTH_ERROR:
case INSUFFICIENT_ACCESS_LEVEL:
throw e;
default:
break;
}
}
try {
if (target.connect(WebApiVersion.UNKNOWN, ServerType.ZEND_SERVER)) {
return target;
}
} catch (WebApiException ex) {
if (target.connect()) {
return target;
}
}
return null;
}
private IZendTarget testConnectAndDetectPort(IZendTarget target)
throws WebApiException, LicenseExpiredException {
WebApiException catchedException = null;
int[] portToTest = possiblePorts;
if (target.getHost().getPort() == -1) {
for (int port : portToTest) {
URL old = target.getHost();
URL host;
try {
host = new URL(old.getProtocol(), old.getHost(), port,
old.getFile());
((ZendTarget) target).setHost(host);
} catch (MalformedURLException e) {
// should never happen
}
try {
return testTargetConnection(target);
} catch (WebApiException e) {
catchedException = e;
}
}
} else {
try {
return testTargetConnection(target);
} catch (WebApiException e) {
catchedException = e;
}
}
if (catchedException != null) {
throw catchedException;
}
return null;
}
/**
* Reads properties files and return values
*
* @return Properties loaded object
*/
private Properties getProperties() {
if (props == null) {
final File file = getPropertiesFile();
if (file == null) {
return null;
}
try {
Properties p = new Properties();
p.load(new FileInputStream(file));
getLogger().info("Loading file " + file.getAbsolutePath());
props = p;
} catch (FileNotFoundException e) {
getLogger().error("File not found " + file.getAbsolutePath());
} catch (IOException e) {
getLogger().error("Error reading " + file.getAbsolutePath());
}
}
return props;
}
}