Code Monkey home page Code Monkey logo

explorviz-archive / explorviz-backend Goto Github PK

View Code? Open in Web Editor NEW
8.0 8.0 5.0 16.77 MB

ExplorViz is a monitoring and visualization approach, which uses dynamic analysis techniques to provide a live trace visualization of large software landscapes. This repository contains the backend.

Home Page: https://www.explorviz.net

License: Apache License 2.0

Java 99.34% Shell 0.38% Dockerfile 0.29%
software-architecture software-visualization

explorviz-backend's People

Contributors

alexander-krause-glau avatar dan0x09 avatar jwegert avatar lotzk avatar malte-hansen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

explorviz-backend's Issues

Insufficient memory

Rarely, when running the explorviz application along with the frontend and the Kieker Sample Application, the landscape service crashes due to insufficient memory.

Error message:

# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 241696768 bytes for committing reserved memory.
# An error report file with more information is saved as:

Relevant specs:

OS: Linux
RAM: 8GB
Java: openjdk version "1.8.0_202"

I can't find a reliable way to reproduce this behavior.

Inter service communication

Frontend uses JWT-based authentication / authorization for requests. Token generation is based on username and password validation.

How should microservices communicate among each other?

Roles are not verified when creating new users

When creating a new user, you can chose arbitrary roles for that new user. Even if these roles do not exist (in the database), the request is not rejected and the user is created. This causes exceptions each time the user is requested, since the reference to such roles can't be resolved.

Tests for auth service

We need well documented tests for this service, since future students should take these as starting point for their tests.

Landscape database

At the moment, landscape objects are persisted by saving them as binary files. We should replace this approach with an actual dbms (e.g. MongoDB).

Further, the landscapes should be saved in valid JSON:API format, to avoid another serilization/deserialization-routine when fetched again.

Refactor Analysis service

Analysis service should process + aggregate incoming Kieker records and send them to the ExplorViz landscape service. At the time of writing, the ExplorViz analysis uses the KiekerAdapter to transform incoming Kieker records to ExplorViz legacy records. So

  • Analysis has to understand, process and aggregate incoming Kieker records
  • Landscape service has to understand, and process the new resulting trace model

Database reconnection pattern

We should allow services to start, even if the necessary database is not online at the moment. We could use a Jersey filter for incoming requests to anonymously notify user about the state of the service.

Then, a service should check every minute or so for a potential reconnection.

Endpoints for user management in authentication service

We require a new resource class for the following user management related tasks:

  • Create single user
  • Create lists of users
  • Change password
  • Get all users
  • Remove single user
  • Remove user by category (e.g. all probands)
  • more ?

Cache landscape objects

The most recently used landscape objects should be held in a cache to avoid I/O. As mentioned in #38, landscape objects will be persisted as json-api strings, identified by unique (numeric) id. We can utilize Redis as an in-memory-cache for those string.

SettingsDescriptor should use sub resource class

At the time of writing, the SettingsDescriptor and default UserSettings share the same endpoint.

TODO SettingsDescriptor should use .../settings/{id}/info.

@dan0x09 This does affect the frontend implementation due to the new endpoint.

User role's descriptor null

When creating a user or changing their properties, the following error is sent to the frontend:

{"errors": [ { "status": "400", "title": "Error", "detail": "Unknown role: {1, null}" } ]}

This happens due to the newly introduced check, whether the role is actually valid or not. However, the check is not the issue.
The role's descriptor is null and not admin. The problem seems to be that the frontend, when sending a request including a role, never sends a role's descriptor - only the id as in the following:

attributes: {username: "rolf2", password: null}
id: "4"
relationships: {roles: {data: [{type: "role", id: "1"}]}}
type: "user"

That probably results in the Role constructor being called with a descriptor that is null.

The id sent by the frontend should, however, be enough. IMO, it should be the backend's job to request the corresponding descriptor from the database and set the role object's descriptor accordingly.

DummyExtension should use Backend Provider

I open this issue here, otherwise we will probably loose track of spread tickets.

Tl;Dr; The source code lines are necessary for extensions to convert Java to JSON-API-conform payload using the backend JSON-API providers.

The DummyExtension uses a seperate provider for JSONAPI. Since the GenericTypeFinder solves our problem of finding runtime (generic) type information, we can fully use the backend JSONAPI providers.

Use the DiscoveryExtension as example for implementing this feature. Additionally add:

GenericTypeFinder.typeMap.putIfAbsent("Timestamp", Timestamp.class);
GenericTypeFinder.typeMap.putIfAbsent("Landscape", Landscape.class);
GenericTypeFinder.typeMap.putIfAbsent("System", net.explorviz.model.System.class);
GenericTypeFinder.typeMap.putIfAbsent("NodeGroup", NodeGroup.class);
GenericTypeFinder.typeMap.putIfAbsent("Node", Node.class);
GenericTypeFinder.typeMap.putIfAbsent("Application", Application.class);
GenericTypeFinder.typeMap.putIfAbsent("Component", Component.class);
GenericTypeFinder.typeMap.putIfAbsent("Clazz", Clazz.class);
GenericTypeFinder.typeMap.putIfAbsent("CommunicationClazz", CommunicationClazz.class);
GenericTypeFinder.typeMap.putIfAbsent("Communication", Communication.class);
GenericTypeFinder.typeMap.putIfAbsent("CommunicationAccumulator", CommunicationAccumulator.class);
GenericTypeFinder.typeMap.putIfAbsent("CommunicationTileAccumulator", CommunicationTileAccumulator.class);
GenericTypeFinder.typeMap.putIfAbsent("DatabaseQuery", DatabaseQuery.class);
GenericTypeFinder.typeMap.putIfAbsent("User", User.class);

to Extension-Application constructor. GenericTypeFinder is a static class, but it seems that both applications have their own scope. Therefore, they do not share this class.

Plugin Manager (Evaluation)

Create Plugin Manager with list of strings ("package strings"). Use these in ResourceConfig with package scanning.

JPA for database

Use JPA for database communication instead of old plain JDBC SQL statements

Landscape-Service generates new Ids and does not use and update old instances

Seems like there is a major bug in the landscape-service that results in using new entities with new Ids (or updating the Id of old entities, not sure) instead of simply updating old values of known entities.

As a result the frontend thinks it gets new records (due to the new id) and the Ember Store grows and eventually the browser crashes due to EXCEPTION_STACK_OVERFLOW.

Todo Fix id handling; Old entities should be reused.

Use String instead of long for Trace Id

A long in java is a 64bit signed integer, the max safe integer is roughly 2^63. In Javascript the max safe integer is roughly 2^53, thus those data types are not matching. For most variables of type long which are sent to the frontend this is no issue in practice because most long variables are incremented step by step - never reaching a number as big as 2^53.

However, trace IDs are generated by the Kieker framework as opposed to the ExplorViz Backend. Since Kieker should handle a lot of incoming traces from different sources, the IDs are not simply incremented. It exists a function in Kieker which maps incoming traces to a variable of type long. This function uses all 64 bits to practically avoid collisions of IDs and thus returns usually an integer which is larger than 2^53.

As a result trace IDs are not interpreted correctly by the frontend and result in colliding trace IDs. To fix this issue we need to either map the big trace IDs to smaller traceIDs in the backend or use a string representation for the trace IDs. The latter is to be preferred, since mapping would be more compute intense and error prone than converting to a string.

Update via timeline is really slow

As mentioned in ExplorViz-Archive/explorviz-frontend#134, the frontend now notifies users about a visualization update. The time between clicking the timeline and the updated visualization is way too long.

The Firefox network tab shows that the actual HTTP request takes so long.

TODO

  • Check if MongoDB refactoring fixed this issue (see #38)
  • If not, check if reverse proxy is responsible for this

Unique id handling

The backend creates unique IDs for every entity at the moment. However, future work includes different extensions that will create entities in the frontend and save them via HTTP. Therefore, IDs must be initially created in the frontend. This introduces bugs, if two entities with the same id and type are stored in the Ember Store.

We require a way to handle these situations. Possible approaches (maybe not applicable) are:

  • Frontend requests unique ID via a entity scaffold, e.g., landscape that contains nothing but the unique id. Then use this scaffold to save the to-be saved entity.
  • Use type string for the id. To-be saved entities have a id with the prefix to-be-generated-by-backend-X, where X is a counter variable used in the frontend.
  • More?

Failing exchange under heavy-load between landscape service and frontend

At the moment, the landscape service uses SSE (server side events) to broadcast the latest landscape every tenth second to any subscribed frontend.

If under heavy load, the landscape service cannot satisfy the "tenth second" update. Therefore, it catches up after a short time, which results in multiple SSE to the frontend. The frontend cannot handle this and eventually crashes.

We need to fix this.

Additionally: Is there any better way to achieve an authorized exchange (publish / subscribe) between these two?

Communication between Microservices

As mentioned in #25, a user (i.e. the frontend) is able to authenticate using JWT. If any service is being required prior to user interaction, the token can be forwarded to that specific service.

If two or more microservices need to talk to each other without previous user interaction, there is no token to be passed. For example: The discovery service needs to fetch data from the landscape service without any user interaction happening beforehand.

An approach to solving this, is to have the microservices provide additional interfaces with the required functionality. These interfaces mustn't be secured by JWT but only be accessible from within the system (the docker container) and unreachable from the outside (the API gateway). This allows internal communication between microservices without the need for a token or authorization at all.

DI bug in landscape service

The config properties mongo.host etc. cannot be read in the MongoHelper, therefore the class uses the default values localhost and port 28018.

This needs to be fixed for the Docker containers.

StackOverflowError during landscape serialization (for Kafka)

This issue might be dependent on the used hardware, since this issue and the following screenshot were both captured on a mid-low windows laptop.

I couldn't reproduce this, but we should investigate this (for example by manually limiting the JVM Heap or something)

explorviz-error

Inject and Config annotation should be used in coexistence at constructor level

At the moment, our custom config annotation does not resolve properties, if used at constructor level with an Inject annotation for injecting non-config related DI-based services.

We require this to optimally unit test classes, since property level injection is error prone. Sure, we could use the InjectMocks annotation of Mockito, but why should we write all this, if a simple constructor-only based DI could solve this and is furthermore the better way to achieve the same behavior.

Property names JSON-API conform

JSON-API expects properties without camel case, e.g. instanceCount -> instance-count. Should we change the names? Workaround in Ember: serializers/application.js

Use ConcurrentHashMap to store <ID, MetaModelObject> pairs

The backend creates objects with a unique ID. If the frontend requests a object by ID (that's the default for Ember findRecord) we need to traverse the landscape tree.

We should keep a ConcurrentHashMap next to the internalLandscape and add new elements to both objects. Backend resources (e.g. to to be developed AgentResource) can then requests objects by ID from this Map.

Example: Frontend requests application with ID 377. Backend returns value for key 377.

Find possible god

Find possible god class when doing layout. Highlight later in visualization

Aggregated communication

Closing a package should result in a thicker communication line, but sometimes it doesn't. Why?

Created user cannot obtain roles

Login with default credentials. Create a user with admin role and login with this user. This new admin-role user cannot create other users.

Timestamp interface exception handling

We need to provide an exception handling for our timestamp resource.
If a timestamp is not available, e.g., missing in the file system, we should return an specified http error code, which can be handled in the frontend.

Kieker empty applicationName property results in wrong application mapping

I am not sure if this issue did really occur, we should first reproduce the following:

  1. Start Backend and Frontend
  2. Start sampleApplication
  3. Stop sampleApplication (after it was at least once visualized)
  4. Change Kieker property "applicationName" in sampleApplication to empty, e.g., kieker.monitoring.applicationName=
  5. Start sampleApplication
  6. Verify if new application or old sampleApplication is used
  7. Report back

Additionally: What happens (with the node in the landscape viz) if a Kieker-instrumented application runs on a different machine, Kieker sends its data to ExplorViz, and the hostname property is empty?

Data model restructuring

In order to use the trace information in the frontend, we need to restructure the data model in the backend first and add a trace entity. Addtionally, we can use this to tidy up the data model as well.

Afterwards, we need the changes need to be implemented in the frontend (ExplorViz-Archive/explorviz-frontend#111)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.