Skip to content

Commit

Permalink
Merge pull request #157 from telefonicaid/hardening/fiqare-perseo-cor…
Browse files Browse the repository at this point in the history
…e-improvements-prelanding

FIX software quality improvement based on ISO25010 recommendations
  • Loading branch information
AlvaroVega authored Feb 5, 2020
2 parents 8286f54 + 52685ce commit 5616ef3
Show file tree
Hide file tree
Showing 51 changed files with 403 additions and 6,486 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,3 @@ hs_err_pid*
target
nb-configuration.xml
nbactions.xml

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ install:
- mvn test -B

before_install:
- mvn clean
- mvn clean
2 changes: 2 additions & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Haredning: add json library as proper dependency in pom.xml (version 20180813) instead of third-party source code
- Hardening: software quality improvement based on ISO25010 recommendations
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ This is the code repository for the EPL-server, named perseo-core.
* [Architecture](documentation/architecture.md)
* [Logs & Alarms](documentation/logs.md)
* O&M
* [Deployment](documentation/deployment.md)
* [Configuration](documentation/config.md)
* [Administration](documentation/admin.md)
* [Deployment](documentation/deployment.md)
* [Configuration](documentation/config.md)
* [Administration](documentation/admin.md)
* [API](documentation/api.md)

* [License](#licence)
Expand Down
6 changes: 3 additions & 3 deletions documentation/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Being this rule working
@Audit
select *,"blood_1_action" as iotcepaction,
ev.BloodPressure? as Pression,
ev.id? as Meter
ev.id? as Meter
from pattern [
every ev=iotEvent(cast(cast(BloodPressure?,String),float)>1.5
and type="BloodMeter")
]
and type="BloodMeter")
]
```
and sending an event
```JSON
Expand Down
14 changes: 7 additions & 7 deletions documentation/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The only dependecy for perseo-core is the servlet engine container for its WAR f

You only need to do this once in your system:

docker build -t perseo .
docker build -t perseo .

The parameter `-t perseo` gives the image a name. This name could be anything, or even include an organization like
`-t org/fiware-perseo`. This name is later used to run the container based on the image.
Expand All @@ -22,12 +22,12 @@ If you want to know more about images and the building process you can find it i
The following line will run the container, using a manually built image (see above),
exposing port `8080`, give it a name -in this case `perseo1`, and present a bash prompt:

docker run -d --name perseo1 -p 8080:8080 perseo
docker run -d --name perseo1 -p 8080:8080 perseo

As a result of this command, there is a PERSEO listening on port 8080 on localhost. Try to see if it works now with

curl localhost:8080/perseo-core/version
curl localhost:8080/perseo-core/version
To get access to the log file of Perseo Core you can run:

```
Expand All @@ -40,7 +40,7 @@ The following line will run the container, from Dockerhub, exposing port `8080`,
and binding it to a [Perseo Front-End](https://github.com/telefonicaid/perseo-fe)
instance (hostname `perseo-frontend`) listening on port 9090.

docker run -d --name perseo_core -h perseocore -p 8080:8080 telefonicaiot/perseo-core:master -perseo_fe_url perseo-frontend:9090
docker run -d --name perseo_core -h perseocore -p 8080:8080 telefonicaiot/perseo-core:master -perseo_fe_url perseo-frontend:9090

A few points to consider:

Expand Down Expand Up @@ -121,5 +121,5 @@ Independently of how the service is installed, the log files will need an extern
Logrotate is installed as RPM dependency along with perseo. The system is configured to rotate every day and whenever the log file size is greater than 100MB (checked very 30 minutes by default):
* For daily rotation: /etc/logrotate.d/logrotate-perseo-daily: which enables daily log rotation
* For size-based rotation:
* /etc/sysconfig/logrotate-perseo-size: in addition to the previous rotation, this file ensures log rotation if the log file grows beyond a given threshold (100 MB by default)
* /etc/cron.d/cron-logrotate-perseo-size: which ensures the execution of etc/sysconfig/logrotate-perseo-size at a regular frecuency (default is 30 minutes)
* /etc/sysconfig/logrotate-perseo-size: in addition to the previous rotation, this file ensures log rotation if the log file grows beyond a given threshold (100 MB by default)
* /etc/cron.d/cron-logrotate-perseo-size: which ensures the execution of etc/sysconfig/logrotate-perseo-size at a regular frecuency (default is 30 minutes)
10 changes: 5 additions & 5 deletions documentation/images/architecture.dot
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
digraph perseocore {
rankdir=LR
rankdir=LR
node [fontname = "arial"];
perseo[shape=circle, style=dashed];
core[label=" core ", shape=circle];
core[label=" core ", shape=circle];

perseo->core[label="rule"]
perseo->core[label="event"]
core->perseo[label="action"]
perseo->core[label="rule"]
perseo->core[label="event"]
core->perseo[label="action"]

}
2 changes: 1 addition & 1 deletion documentation/logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Logs have levels `FATAL`, `ERROR`, `INFO` and `DEBUG`. The log level must be set in the configuration file `log4j.xml`

```xml
<priority value="info" />
<priority value="info" />
```

Each log line contains several fields of the form *name*`=` *value*, separated by `|`
Expand Down
10 changes: 10 additions & 0 deletions perseo-main/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@
<groupId>com.telefonica.iot</groupId>
<version>1.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

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

Expand Down Expand Up @@ -53,7 +54,7 @@ private Configuration() {
private static long maxAge;

static {
LOGGER.debug("Configuration init: " + reload());
LOGGER.debug(String.format("Configuration init: %s",reload()));
}

/**
Expand Down Expand Up @@ -95,21 +96,21 @@ public static synchronized boolean reload() {
// Add actions/do path if perseoFeURLEnv not contains it yet
actionRule = perseoFeURLEnv.contains(actionPath) ? perseoFeURLEnv : perseoFeURLEnv + actionPath;
} else {
LOGGER.error("Invalid value for " + PERSEO_FE_URL_ENV + ": " + perseoFeURLEnv);
LOGGER.error(String.format("Invalid value for %s: %s",PERSEO_FE_URL_ENV, perseoFeURLEnv));
return false;
}
LOGGER.info("actionRule configuration is: " + actionRule);
LOGGER.info(String.format("actionRule configuration is: %s",actionRule));

// Get MAX_AGE from env var if exist, else default
String maxAgeEnv = System.getenv(PERSEO_MAX_AGE_ENV);
// Check maxAge numerical value
try {
maxAge = maxAgeEnv != null ? Long.parseLong(maxAgeEnv) : Long.parseLong(defaultMaxAge);
} catch (NumberFormatException nfe) {
LOGGER.error("Invalid value for " + PERSEO_MAX_AGE_ENV + ": " + nfe);
LOGGER.error(String.format("Invalid value for %s: %s",PERSEO_MAX_AGE_ENV,nfe));
return false;
}
LOGGER.info("maxAge configuration is: " + maxAge);
LOGGER.info(String.format("maxAge configuration is: %s",maxAge));

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @author brox
*/
public final class Constants {
private Constants() { };
private Constants() {}
public static final String SERVICE_FIELD = "service";
public static final String SUBSERVICE_FIELD = "subservice";
public static final String CORRELATOR_HEADER = "fiware-correlator";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.log4j.MDC;
import org.json.JSONException;
import org.json.JSONObject;
import org.owasp.encoder.Encode;

/**
*
Expand All @@ -42,7 +43,7 @@
public class EventsServlet extends HttpServlet {

private static final Logger logger = LoggerFactory.getLogger(EventsServlet.class);
EPServiceProvider epService;
private static EPServiceProvider epService;

@Override
public void init() {
Expand Down Expand Up @@ -76,25 +77,25 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
Utils.putCorrelatorAndTrans(request);
logger.debug("events doPost");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
response.setContentType("application/json;charset=UTF-8");
try {
StringBuilder sb = new StringBuilder();
String eventText = Utils.getBodyAsString(request);
logger.info("incoming event:" + eventText);
logger.info(String.format("incoming event: %s", eventText));
org.json.JSONObject jo = new JSONObject(eventText);
logger.debug("event as JSONObject: " + jo);
logger.debug(String.format("event as JSONObject: %s", jo));
Map<String, Object> eventMap = Utils.JSONObject2Map(jo);
logger.debug("event as map: " + eventMap);
logger.debug(String.format("event as map: %s" , eventMap));
epService.getEPRuntime().sendEvent(eventMap, Constants.IOT_EVENT);
logger.debug("event was sent: " + eventMap);
} catch (JSONException je) {
logger.error("error: " + je);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
out.printf("{\"error\":\"%s\"}\n", je.getMessage());

} finally {
out.close();
logger.debug(String.format("event was sent: %s", eventMap));
} catch (Exception je) {
try {
logger.error(String.format("error: %s" ,je));
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().print(String.format("{\"error\":\"%s\"}%n", Encode.forHtmlContent(je.getMessage())));
} catch (IOException exception) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ public class GenericListener implements UpdateListener {
*/
@Override
public void update(EventBean[] newEvents, EventBean[] oldEvents) {
try {
HashMap<String, JSONObject> rules = TimeRulesStore.getInstance().getAllRulesInfo();
try {
for (EventBean event : newEvents) {

JSONObject jo = Utils.Event2JSONObject(event);
Expand All @@ -64,23 +63,23 @@ public void update(EventBean[] newEvents, EventBean[] oldEvents) {

// Is a timed Rule. Set special headers using rule saved information
Utils.setTimerRuleHeaders(rule);
LOGGER.info("Firing temporal rule: " + event);
LOGGER.info(String.format("Firing temporal rule: %s",event));

} else {

LOGGER.info("Firing Rule: " + event);
LOGGER.info(String.format("Firing Rule: %s",event));
}

LOGGER.debug("result errors: " + jo.optJSONObject("errors"));
LOGGER.debug("result json: " + jo);
LOGGER.debug(String.format("result errors: %s",jo.optJSONObject("errors")));
LOGGER.debug(String.format("result json: %s", jo));

boolean ok = Utils.DoHTTPPost(Configuration.getActionURL(), jo.toString());
if (!ok) {
LOGGER.error("action post failed");
}
}
} catch (PropertyAccessException pae) {
LOGGER.error("doing action " + pae);
LOGGER.error(String.format("doing action %s",pae));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.owasp.encoder.Encode;


/**
Expand Down Expand Up @@ -65,21 +66,28 @@ public class LogLevelServlet extends HttpServlet {
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String levelName = request.getParameter("level");
logger.info("changing log level to " + levelName);
Level level = levels.get(levelName);
if (level == null) {
logger.error("invalid log level: " + levelName);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
try {
String levelName = request.getParameter("level");
logger.info(String.format("changing log level to %s",levelName));
Level level = levels.get(levelName);
if (level == null) {
logger.error(String.format("invalid log level: %s",levelName));
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().print("{\"errorMessage\":\"invalid log level\"}");
return;
}
synchronized (mutex) {
LogManager.getRootLogger().setLevel(level);
}
response.setStatus(HttpServletResponse.SC_OK);
} catch (IOException e) {
logger.error("IOException in log level");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().print("{\"errorMessage\":\"invalid log level\"}");
return;
}
synchronized (mutex) {
LogManager.getRootLogger().setLevel(level);
}
response.setStatus(HttpServletResponse.SC_OK);

}

/**
Expand All @@ -95,11 +103,18 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.debug("getting log level");
synchronized (mutex) {
String currentLevel = LogManager.getRootLogger().getLevel().toString();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
response.getOutputStream().print("{\"level\":\""+ currentLevel +"\"}");
try {
String currentLevel = LogManager.getRootLogger().getLevel().toString();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
response.getOutputStream().print(String.format("{\"level\":\"%s\"}",Encode.forHtmlContent(currentLevel)));
} catch (IOException e) {
logger.error("IOException in log level");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

}
}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class Result {
Result(int code, String msg) {
this.statusCode = code;
this.message = msg;

}

/**
Expand Down
Loading

0 comments on commit 5616ef3

Please sign in to comment.