Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recall final status transitions handled more gracefully #129

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
29 changes: 6 additions & 23 deletions src/main/java/it/grid/storm/config/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@ public class Configuration {
private static final String REST_SERVICES_PORT_KEY = "storm.rest.services.port";
private static final String REST_SERVICES_MAX_THREAD = "storm.rest.services.maxthread";
private static final String REST_SERVICES_MAX_QUEUE_SIZE = "storm.rest.services.max_queue_size";
private static final String RETRY_VALUE_KEY_KEY = "tape.recalltable.service.param.retry-value";
private static final String STATUS_KEY_KEY = "tape.recalltable.service.param.status";
private static final String TASKOVER_KEY_KEY = "tape.recalltable.service.param.takeover";
private static final String STORM_PROPERTIES_VERSION_KEY = "storm.properties.version";
private static final String TAPE_SUPPORT_ENABLED_KEY = "tape.support.enabled";
Expand Down Expand Up @@ -185,12 +183,15 @@ public class Configuration {

private Configuration() throws ConfigurationException {

String filePath = getProperty(CONFIG_FILE_PATH, DEFAULT_STORM_CONFIG_FILE);
final int DEFAULT_REFRESH_RATE = 0;
final String DEFAULT_CONFIG_FILE_PATH = "/etc/storm/backend-server/storm.properties";

String filePath = getProperty(CONFIG_FILE_PATH, DEFAULT_CONFIG_FILE_PATH);
int refreshRate;
try {
refreshRate = Integer.valueOf(getProperty(REFRESH_RATE));
} catch (NumberFormatException e) {
refreshRate = DEFAULT_STORM_CONFIG_REFRESH_RATE;
refreshRate = DEFAULT_REFRESH_RATE;
}
cr = new ConfigReader(filePath, refreshRate);
}
Expand All @@ -200,7 +201,7 @@ private Configuration() throws ConfigurationException {
*/
public static Configuration getInstance() {

return Configuration.instance;
return instance;
}

/**
Expand Down Expand Up @@ -1144,24 +1145,6 @@ public int getRestServicesMaxQueueSize() {
return cr.getConfiguration().getInt(REST_SERVICES_MAX_QUEUE_SIZE, RestServer.DEFAULT_MAX_QUEUE_SIZE);
}

/**
* Method used to retrieve the key string used to pass RETRY-VALUE parameter to Recall Table
* service key="tape.recalltable.service.param.retry-value";
*/
public String getRetryValueKey() {

return cr.getConfiguration().getString(RETRY_VALUE_KEY_KEY, "retry-value");
}

/**
* Method used to retrieve the key string used to pass RETRY-VALUE parameter to Recall Table
* service key="tape.recalltable.service.param.status";
*/
public String getStatusKey() {

return cr.getConfiguration().getString(STATUS_KEY_KEY, "status");
}

/**
* Method used to retrieve the key string used to pass RETRY-VALUE parameter to Recall Table
* service key="tape.recalltable.service.param.takeover";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,9 @@ public TapeRecallCatalog() {
*
* @param groupTaskId @param newValue
*/
public void changeGroupTaskRetryValue(UUID groupTaskId, int newValue) {
public void changeGroupTaskRetryValue(UUID groupTaskId, int newValue) throws DataAccessException {

try {
tapeRecallDAO.setGroupTaskRetryValue(groupTaskId, newValue);
} catch (DataAccessException e) {
log.error("Unable to takeover a task", e);
}
tapeRecallDAO.setGroupTaskRetryValue(groupTaskId, newValue);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package it.grid.storm.tape.recalltable.model;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertiesParser implements RequestDataParser<Properties> {

@Override
public Properties parse(InputStream input) throws IOException {

Properties props = new Properties();
props.load(input);
return props;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import it.grid.storm.persistence.exceptions.DataAccessException;
import it.grid.storm.persistence.model.TapeRecallTO;
import it.grid.storm.tape.recalltable.TapeRecallCatalog;
import it.grid.storm.tape.recalltable.TapeRecallException;

import java.util.Date;
import java.util.UUID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,136 +17,144 @@

package it.grid.storm.tape.recalltable.model;

import it.grid.storm.namespace.NamespaceDirector;
import it.grid.storm.namespace.StoRI;
import it.grid.storm.srm.types.InvalidTSURLAttributesException;
import it.grid.storm.srm.types.TSURL;
import it.grid.storm.util.SURLValidator;
import it.grid.storm.util.TokenValidator;
import static java.lang.String.format;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;

import java.util.StringTokenizer;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PutTapeRecallStatusValidator implements RequestValidator {

private static final Logger log = LoggerFactory
.getLogger(PutTapeRecallStatusValidator.class);

private String requestToken = null;
private StoRI stori = null;
private String inputString = null;
private Response validationResponse = null;

public PutTapeRecallStatusValidator(String inputString) {
import it.grid.storm.namespace.NamespaceDirector;
import it.grid.storm.namespace.StoRI;
import it.grid.storm.srm.types.InvalidTSURLAttributesException;
import it.grid.storm.srm.types.TSURL;
import it.grid.storm.util.SURLValidator;
import it.grid.storm.util.TokenValidator;

this.inputString = inputString;
}
public class PutTapeRecallStatusValidator implements RequestValidator {

/**
* Parse and validate input.
* <p>
* If this method returns <code>true</code> the input data can be retrieved
* with the methods: {@link #getRequestToken()} and {@link #getStoRI()}.
* <p>
* If this method returns <code>false</code> the response can be retrieved
* with the method {@link #getResponse()}.
*
* @return <code>true</code> for successful validation process,
* <code>false</code> otherwise.
*/
public boolean validate() {
private static final Logger log = LoggerFactory.getLogger(PutTapeRecallStatusValidator.class);

StringTokenizer tokenizer = new StringTokenizer(inputString, "\n");
public static final String REQUEST_TOKEN_KEY = "requestToken";
public static final String SURL_KEY = "surl";

if (tokenizer.countTokens() != 2) {
public static final String NOT_FOUND_PROPERTY = "Invalid body. Not found property %s.";
public static final String INVALID_TOKEN = "Invalid token: %s.";
public static final String INVALID_SURL = "Invalid SURL: %s.";

log.trace("putTaskStatus() - input error");
private InputStream input = null;

validationResponse = Response.status(400).build();
return false;
private Response validationResponse = null;

}
private String requestToken = null;
private StoRI stori = null;

String requestTokenInput = tokenizer.nextToken();
String surlInput = tokenizer.nextToken();
public PutTapeRecallStatusValidator(InputStream input) {

if ((!requestTokenInput.startsWith("requestToken="))
|| (!surlInput.startsWith("surl="))) {
this.input = input;
}

log.trace("putTaskStatus() - input error");
/**
* Parse and validate input.
* <p>
* If this method returns <code>true</code> the input data can be retrieved with the methods:
* {@link #getRequestToken()} and {@link #getStoRI()}.
* <p>
* If this method returns <code>false</code> the response can be retrieved with the method
* {@link #getResponse()}.
*
* @return <code>true</code> for successful validation process, <code>false</code> otherwise.
*/
public boolean validate() {

validationResponse = Response.status(400).build();
return false;
Properties props;
PropertiesParser parser = new PropertiesParser();
try {
props = parser.parse(input);
} catch (IOException e) {
log.error(e.getMessage(), e);
validationResponse = Response.status(INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
return false;
}

}
if (!props.containsKey(REQUEST_TOKEN_KEY)) {
validationResponse = Response.status(BAD_REQUEST).entity(format(NOT_FOUND_PROPERTY, REQUEST_TOKEN_KEY)).build();
return false;
}

requestToken = requestTokenInput
.substring(requestTokenInput.indexOf('=') + 1);
String surlString = surlInput.substring(surlInput.indexOf('=') + 1);
if (!props.containsKey(SURL_KEY)) {
validationResponse = Response.status(BAD_REQUEST).entity(format(NOT_FOUND_PROPERTY, SURL_KEY)).build();
return false;
}

if ((requestToken.length() == 0) || (surlString.length() == 0)) {
requestToken = props.getProperty(REQUEST_TOKEN_KEY);

log.trace("putTaskStatus() - input error");
if (requestToken.length() == 0 || !TokenValidator.valid(requestToken)) {
validationResponse = Response.status(BAD_REQUEST).entity(format(INVALID_TOKEN, requestToken)).build();
return false;
}

validationResponse = Response.status(400).build();
return false;
String surlString = props.getProperty(SURL_KEY);

}
if (surlString.length() == 0) {
validationResponse = Response.status(BAD_REQUEST).entity(format(INVALID_SURL, surlString)).build();
return false;
}

if(!TokenValidator.valid(requestToken)){
validationResponse = Response.status(400).entity("Invalid token: " + requestToken +" \n\n").build();
return false;
}

if (!validateSurl(surlString)) {
return false;
}
if (!validateSurl(surlString)) {
validationResponse = Response.status(BAD_REQUEST).entity(format(INVALID_SURL, surlString)).build();
return false;
}

return true;
}
return true;
}

public String getRequestToken() {
public String getRequestToken() {

return requestToken;
}
return requestToken;
}

public StoRI getStoRI() {
public StoRI getStoRI() {

return stori;
}
return stori;
}

public Response getResponse() {
public Response getResponse() {

return validationResponse;
}
return validationResponse;
}

private boolean validateSurl(String surlString) {
private boolean validateSurl(String surlString) {

TSURL surl;
TSURL surl;

if(!SURLValidator.valid(surlString)){
validationResponse = Response.status(400).entity("Invalid surl: " + surlString + "\n\n").build();
return false;
}

try {
if (!SURLValidator.valid(surlString)) {
validationResponse =
Response.status(400).entity("Invalid surl: " + surlString + "\n\n").build();
return false;
}

surl = TSURL.makeFromStringValidate(surlString);
try {

surl = TSURL.makeFromStringValidate(surlString);

} catch (InvalidTSURLAttributesException e) {
validationResponse = Response.status(400).build();
return false;
}
try {
stori = NamespaceDirector.getNamespace().resolveStoRIbySURL(surl);
} catch (Exception e) {
log.warn("Unable to build a stori for surl {} UnapprochableSurlException: {}" , surl , e.getMessage(),e);
return false;
}
return true;
}
} catch (InvalidTSURLAttributesException e) {
validationResponse = Response.status(400).build();
return false;
}
try {
stori = NamespaceDirector.getNamespace().resolveStoRIbySURL(surl);
} catch (Exception e) {
log.warn("Unable to build a stori for surl {} UnapprochableSurlException: {}", surl,
e.getMessage(), e);
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package it.grid.storm.tape.recalltable.model;

public class PutUpdateTaskLogic {

}
Loading