//TODO: document the exceptions
public void ServerFunction(HttpListenerContext context)
{
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
if (!atomic)
{
// Debug messages
if (log.IsDebugEnabled)
{
log.Debug("Server free from atomic operations!");
log.Debug("Getting requested path...");
}
// Request analysis - only accept url equals to '/'
string path = HttpUtility.UrlDecode(request.Url.AbsolutePath);
if (!path.Equals("/"))
{
sendResponse(response, "", HttpStatusCode.NotFound);
log.Error("Invalid url: " + path);
}
else
{
string queryString = "";
string function = "";
string orderBy = "";
string defaultField = "";
string type = "";
string user = "";
// Debug messages
if (log.IsDebugEnabled)
{
log.Debug("Valid path request!");
log.Debug("Getting query parameters...");
}
Dictionary<string, object> parameters = GetQueryParams(request.Url.Query);
// Debug messages
if (log.IsDebugEnabled)
{
log.Debug("Parameters: " + request.Url.Query);
log.Debug("Catch every parameter...");
}
try
{
queryString = ReadValue(parameters, "q", "Query");
orderBy = ReadValue(parameters, "orderBy", "OrderBy");
defaultField = ReadValue(parameters, "defaultField", "defaultField");
function = ReadValue(parameters, "f", "Function");
if (function == null)
{
log.Error("Invalid function");
sendResponse(response, "Invalid function", HttpStatusCode.BadRequest);
}
user = ReadValue(parameters, "u", "User");
type = ReadValue(parameters, "t", "type");
if (user == "" && (type == "nivelDocumental" || type == ""))
{
log.Error("Invalid user");
sendResponse(response, "Invalid user", HttpStatusCode.BadRequest);
}
}
catch (Exception e)
{
log.Error("Error getting parameters", e);
sendResponse(response, "", HttpStatusCode.PreconditionFailed);
return;
}
switch (function)
{
case "search":
try
{
string responseString;
switch (type)
{
case "tipologias":
tSearcher = new TipologiasSearcher(orderBy, defaultField); //
tSearcher.OrderBy = orderBy;
responseString = tSearcher.Search(queryString);
tSearcher.Close(); //
break;
case "assuntos":
aSearcher = new AssuntosSearcher(orderBy, defaultField); //
aSearcher.OrderBy = orderBy;
responseString = aSearcher.Search(queryString);
aSearcher.Close(); //
break;
case "produtor":
pSearcher = new ProdutorSearcher(orderBy, defaultField); //
pSearcher.OrderBy = orderBy;
responseString = pSearcher.Search(queryString);
pSearcher.Close(); //
break;
case "unidadeFisica":
ufSearcher = new UnidadeFisicaSearcher(orderBy, defaultField); //
ufSearcher.OrderBy = orderBy;
responseString = ufSearcher.Search(queryString);
ufSearcher.Close(); //
break;
case "nivelDocumental":
ndSearcher = new NivelDocumentalSearcher(orderBy, defaultField, ndCache); //
ndSearcher.OrderBy = orderBy;
responseString = ndSearcher.Search(queryString, System.Convert.ToInt64(user));
ndSearcher.Close(); //
break;
case "nivelDocumentalInternet":
ndiSearcher = new NivelDocumentalInternetSearcher(orderBy, defaultField); //
ndiSearcher.OrderBy = orderBy;
responseString = ndiSearcher.Search(queryString);
ndiSearcher.Close(); //
break;
case "nivelDocumentalComProdutores":
ndcpSearcher = new NivelDocumentalComProdutoresSearcher(orderBy, defaultField); //
ndcpSearcher.OrderBy = orderBy;
responseString = ndcpSearcher.Search(queryString);
ndcpSearcher.Close(); //
break;
default:
throw new Exception(string.Format("Invalid search type: {0}", type));
}
sendResponse(response, responseString, HttpStatusCode.OK);
}
catch (Exception e)
{
log.Error("Error searching for: " + queryString, e);
sendResponse(response, "Sintaxe inválida!", HttpStatusCode.BadRequest);
}
break;
case "update":
try
{
switch (type)
{
case "tipologias":
Update(request, UpdateType.Tipologia);
break;
case "assuntos":
Update(request, UpdateType.Assunto);
break;
case "produtor":
Update(request, UpdateType.Produtor);
break;
case "unidadeFisica":
Update(request, UpdateType.UnidadeFisica);
break;
case "nivelDocumental":
case "":
Update(request, UpdateType.NivelDocumental);
break;
case "nivelDocumentalInternet":
Update(request, UpdateType.NivelDocumentalInternet);
break;
case "nivelDocumentalComProdutores":
Update(request, UpdateType.NivelDocumentalComProdutores);
break;
default:
throw new Exception(string.Format("Invalid search type: {0}", type));
}
sendResponse(response, "", HttpStatusCode.OK);
}
// It's not an error it's a feature :)
catch (NoPostDataException e)
{
log.Error(e.Message, e);
sendResponse(response, "", HttpStatusCode.OK);
}
catch (Exception e)
{
log.Error("Error updating the index", e);
sendResponse(response, "", HttpStatusCode.InternalServerError);
}
break;
case "createIndex":
try
{
atomic = true;
sendResponse(response, "", HttpStatusCode.OK);
// Debug messages
log.Debug("Creating all indexes...");
UnidadeFisicaUpdater ufUpdater = new UnidadeFisicaUpdater();
ufUpdater.Optimize();
NivelDocumentalUpdater ndUpdater = new NivelDocumentalUpdater();
ndUpdater.Optimize();
// Debug messages
log.Debug("Indexes created.");
}
catch (Exception ex)
{
log.Error("Error creating the index", ex);
}
finally
{
atomic = false;
}
break;
case "ping":
try
{
sendResponse(response, "pong", HttpStatusCode.OK);
log.Debug("Ping response sent");
}
catch (Exception e)
{
log.Error("Ping response fail!", e);
}
break;
default:
try
{
log.Info("Invalid Function: " + function);
sendResponse(response, "", HttpStatusCode.NotImplemented);
}
catch (Exception e)
{
log.Error("Default command error.", e);
}
break;
}
}
}
else
{
try
{
log.Debug("Service call while in atomic state.");
sendResponse(response, "Atomic function", HttpStatusCode.ServiceUnavailable);
}
catch (Exception e)
{
log.Error("Error sending 'atomic' information to client", e);
}
}
}