Pass Data between Multiple Applications in Java [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
The community is reviewing whether to reopen this question as of 9 months ago.
Improve this question
I have a project that was started and orchestrated by someone wayyyyyy more talented than I, and I've hit a point that I can't figure how to bridge.
This is a Java/JavaFX/Spring Boot project, and NOT a Swing project. I see a lot of answers re: Swing. Both applications are also set up in Gradle, so both applications have their own separate ./gradlew bootRun commands and are running in CentOS 7. Both applications have their own, separate, main() methods. I believe the original design was intended, purposefully, to remove any access to the data from the GUI, entirely, which is the reason for the separation. I'm just having a tough time finding a way to pass necessary data back and forth.
There are separate applications that are designed to work together.
**Kiosk** which houses the GUI elements and GUI-related controllers
**Governor** which houses an API and an APP application. The API, as of now, is helping with Source and File interfaces. The APP houses an H2 database (all stored from JSON files, but the content is irrelevant for this particular question), a User package (which houses the User data that feeds the H2 database), and a Source package (which does all the files methods)
What I want to do is:
Get the username and password, supplied by the user at the **Kiosk** level, and pass that somehow into the **Governor**.
Once I can pass the data, I know how to do the rest, to check against the db and verify if the user has valid credentials or not, etc.
Once I have a boolean value (let's call id validUser), I want to pass that information back from the **Governor** to the **Kiosk**, and I can move on from there.
I don't have any code to copy and paste, so I am hoping that the description above is enough to point me in the right direction. I have tried googling all over for "pass data between separate java applications", "separate gui and logic java application", and everything you can think of, but I've hit a wall.
I'm happy to provide any other information you might need, and I'm not looking for anyone to write the code for me, but if you have any examples you've seen, or a concept I may not be familiar with that would help me pass this data back and forth, I would be eternally grateful!
*** Edit *** Trying to add MVP as best I can. Hopefully everything needed to answer question above can be gleaned from below.
Kiosk/LoginController
#Component
public class LoginController extends Controller {
#FXML
TextField username;
#FXML
TextField password;
#FXML
Button loginButton;
#FXML
public void tryLogin() {
UserServices userServices = new UserServices();
String usernameEntered = username.textProperty().getValue();
String passwordEntered = password.textProperty().getValue();
userServices.validateUser(usernameEntered, passwordEntered);
// ... other non-related methods re: tryLogin()
}
}
Kiosk/UserServices
public class UserServices {
public boolean validateUser(String username, String password) {
// **** How do I pass the args (username and password) to Governor?
if (!userFound) {
return false; // user not found, deny entry
}
return true; // allow entry
}
}
}
Governor/API/FileEntry
Note: This file is only a sample of an API module interacting with KIOSK--I do not understand this completely--again, doing the best I can with my limited resources; I believe I need to create my own API User module, but unsure how to proceed)
#JsonDeserialize(as = DefaultFileEntry.class)
public interface FileEntry {
Path getPath();
boolean isDirectory();
#JsonIgnore
default Optional<String> getName() {
if (getPath().getFileName() == null) {
return Optional.empty();
} else {
return Optional.of(getPath().getFileName().toString());
}
}
}
Governor/APP/UserRepository
public interface UserRepository extends JpaRespository<User, String> {
User findByUsername(String username);
}
Governor/APP/UserService
#Service
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// SQL methods to create database, if necessary, search, create, update, and delete users
}

There are several ways to for applications to share data with one another:
JMS, AMQ, or some other messaging system.
A shared database where applications poll for changes.
Open up a REST endpoint that each application can call to update each other. Be sure to secure with certs so outsider can't use them.

Related

How to initialize multiple times the same Component with different dependencies?

I am currently have a spring service consuming an REST service via autogenerated code.
I placed an internal interface to have an abstraction from the REST interface since it is still in development.
The REST service is in fact two on the same host.
So I generate two times code having two components I can inject into my internal interface implementation.
In the interface implementation I do adapt the base paths of the REST client components via #PostConstruct since the URL is dependent on the deployment environment.
This works so far so good. Even though I believe it would be better to adapt the base path not in the internal interface implementation but instead in another place.
Thankful for any hints here.
The Problem
Now the tricky part.
The REST Services I consume exists multiple times with different data in the environment.
Some times there are two, some times three and so on.
The user of our website should be able to select which backend he wants to consume.
The information about which service backends are available should be configurable for the environment.
To be able to configure these environment dependent I would thought about adding a map in the properties like:
service-name: url
second-name: url
and so on.
This map would contain a default with the always existing service.
Via environment variables it can be overwritten to list more backend services.
So, now I want to be able to route the website request to the chosen backend service.
My idea is, that I would need some kind of service.
The service holds the internal interfaces with the different backend instances and can identify which to use based on the name.
The question is now, how to build this with Spring?
More specifically:
How do I construct multiple time my InternalRestClient with different dependencies?
How can I tell them apart/Identify and use them?
Thank you very much for your suggestions in advance.
Code Examples
The internal Rest Interface
public interface InternalRestClient {
String someAbstractMethodUsingBothServices(String someDate);
}
The Implementation
#Service
public class InternalRestClientImpl implements InternalRestClient{
#Value("${url}")
private String url;
private FirstRestService firstService;
private SecondRestService secondService;
public InternalRestClientImpl(FirstRestService firstService, SecondRestService secondService) {
this.firstService = firstService;
this.secondService = secondService;
}
#PostConstruct
void correctPaths() {
firstService.setBasePath(url);
secondService.setBasePath(url);
}
#Override
public String someAbstractMethodUsingBothServices(String someDate) {
return null;
}
}
The autogenerated openapi components
#Component
public class FirstRestService {
private String basePath;
public void setBasePath(String basePath) {
this.basePath = basePath;
}
// some methods
}
#Component
public class SecondRestService {
private String basePath;
public void setBasePath(String basePath) {
this.basePath = basePath;
}
// some other methods
}

How to avoid anemic data model? Can repositories be injected into entities?

I have an immutable User entity:
public class User {
final LocalDate lastPasswordChangeDate;
// final id, name, email, etc.
}
I need to add a method that will return information if the user's password must be changed i.d. it has not been changed for more than the passwordValidIntervalInDays system setting.
The current approach:
public class UserPasswordService {
private SettingsRepository settingsRepository;
#Inject
public UserPasswordService(SettingsRepository settingsRepository) {
this.settingsRepository = settingsRepository;
}
public boolean passwordMustBeChanged(User user) {
return user.lastPasswordChangeDate.plusDays(
settingsRepository.get().passwordValidIntervalInDays
).isBefore(LocalDate.now());
}
}
The question is how to make the above code more object oriented and avoid the anemic domain model antipattern? Should the passwordMustBeChanged method be moved to User if so how to access SettingsRepository, should it be injected into User's constructor, or should a Settings instance be provided to the ctor, or should the passwordMustBeChanged method require a Settings instance to be provided?
The code of Settings and SettingsRepository is not important, but for completness, here it is:
public class Settings {
int passwordValidIntervalInDays;
public Settings(int passwordValidIntervalInDays) {
this.passwordValidIntervalInDays = passwordValidIntervalInDays;
}
}
public class SettingsRepository {
public Settings get() {
// load the settings from the persistent storage
return new Settings(10);
}
}
For a system-wide password expiration policy your approach is not that bad, as long as your UserPasswordService is a domain service, not an application service. Embedding the password expiration policy within User would be a violation of the SRP IMHO, which is not much better.
You could also consider something like (where the factory was initialized with the correct settings):
PasswordExpirationPolicy policy = passwordExpirationPolicyFactory().createDefault();
boolean mustChangePassword = user.passwordMustBeChanged(policy);
//class User
public boolean passwordMustBeChanged(PasswordExpirationPolicy policy) {
return policy.hasExpired(currentDate, this.lastPasswordChangeDate);
}
If eventually the policy can be specified for individual users then you can simply store policy objects on User.
You could also make use of the ISP with you current design and implement a PasswordExpirationPolicy interface on your UserPasswordService service. That will give you the flexibility of refactoring into real policy objects later on without having to change how the User interacts with the policy.
If you had a Password value object you may also make things slightly more cohesive, by having something like (the password creation date would be embedded in the password VO):
//class User
public boolean passwordMustBeChanged(PasswordExpirationPolicy policy) {
return this.password.hasExpired(policy);
}
just to throw out another possible solution would be to implement a long-running process that could do the expiration check and send a command to a PasswordExpiredHandler that could mark the user with having an expired password.
I have stumbled upon a document that provides an answer to my question:
A common problem in applying DDD is when an entity requires access to data in a repository or other gateway in order to carry out a business operation. One solution is to inject repository dependencies directly into the entity, however this is often frowned upon. One reason for this is because it requires the plain-old-(C#, Java, etc…) objects implementing entities to be part of an application dependency graph. Another reason is that is makes reasoning about the behavior of entities more difficult since the Single-Responsibility Principle is violated. A better solution is to have an application service retrieve the information required by an entity, effectively setting up the execution environment, and provide it to the entity.
http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/

Java EE application and "global" variables

we have a Java EE application with primefaces and we are wondering if there's a way to have a "global" application variable.
I mean: imagine user1 is editing document1, when user2 try to access document1 we'd like to show a message: "User1 is already editing this document".
So, we have to use something "global" for keep track of user action or document locking and so on, what's the best way to achieve this?
I've search the internet but opinion differs and generally no working examples are provided, so link and pointer are welcome!
EDIT: the above is just an example, please not focus on "documents", you can call it "resources", or whatever you like. I've used the document lock problem as an example, but it can be a total counter or something else that need to be stores at application level.
What I'm asking (and sorry if it was not clear) is not how to manage document locking, but what's the best way to have a "global" variable at application level in Java EE, if it's possible.
Thank you
Just curious: why if I add "hola," or "hi," as first line it disappear when I save the edit?
If you want to save something globally, in Java EE 6+ it should use the Application Scope
http://docs.oracle.com/javaee/6/api/javax/enterprise/context/ApplicationScoped.html
For example:
#ApplicationScoped
class Global {
void setDocInUse(boolean) { ... }
boolean isDocInUse() { ... }
}
#RequestScoped
class MyDocEditor {
#Inject Global global;
public void edit() {
if (global.isDocInUse()) { ... }
else { ... }
}
}
For most simple cases you can use a static field inside your managed beans for that purpose because it will be shared by all the instances of your managed bean. For example, let us imagine that to edit documents you users interact with the following bean:
#ManagedBean
#ViewScoped
public class DocumentManager {
private static Map<Long, String> editedDocs = new HashMap<>();
private Document selectedDoc;
}
Then let us imagine that after users have selected the document (for example from the dataTable so that it gets into the selectedDoc field) they get the document editing page by clicking on a button which action attribute points to the method editDocument like this:
then in your editDocument method we add the document's id and username of the user that clicked on the button to the mapping that tracks presently edited documents.
public String editDocument() {
if (!editedDocs.contains(selectedDoc.getId())) {
String username = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
editedDocs.put(selectedDoc.getId(), username);
String msg = "User " + username + " is already editing the document";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
}
return theAddressOfEditDocumentPage;
}
Please do not forget to delete the document id and the username from the editedDocs when the user leaves the edit page (by clicking Save or Cancel buttons).
Another possibility is to store such mapping externally (e.g. in the database)

Implementing secure native Play Framework 2.3.x (Java style) authentication

First of all, I am fully aware of the authentication modules that are available to Play. That said, I am unable to implement even the simplest example code from let's say SecureSocial. With a little bit of research it became clear that a lot of things were broken in their example code provided here when the Play Framework updated to version 2.3.x.
With the help of online docs and the excellent video tutorial by Philip Johnson on implementing standard (unsafe) authentication I did succesfully implemented the following:
// Class which is used by the #Security annotation
public class Secured extends Security.Authenticator {
#Override
public String getUsername(Context ctx) {
return ctx.session().get("auth");
}
#Override
public Result onUnauthorized(Context ctx) {
return redirect(routes.Application.login());
}
}
// Controller class that serves routes
public class Application extends Controller {
#Security.Authenticated(Secured.class)
public static Result index() {
return ok(index.render("Your new application is ready."));
}
public static Result login() {
session().clear();
session("auth", "a1234"); // dummy data simulating succesful login
returning redirect(routes.Application.index());
}
}
I need to ultimately implement a safe login system to authenticate users.
My question is two-sided. What would be the better of the following: 'reinventing the wheel' (at least partly) by taking the working code base and improving it or give implementing one of the authentication modules another shot?
We all do not like reinventing the wheel, that said, I have a much better chance of succesfully compiling when I made it myself it seems...
I am aware that for a wholesome security-in-depty (a.k.a. layered security) a secure connection implementation is also needed (HTTPS with TLS1.2` at the time of writing). This is beyond the scope of my question.
I don't know if there's a right answer to this question. Whether to build your own framework or to try an existing framework (which might not work perfectly) is a matter for your own judgement. Personally, I'd probably use SecureSocial as a starting point but then write my own code if I couldn't get it working. It sounds like this is the approach you've already tried.
To use SecureSocial you'd probably need to check out the master branch and build from source. It might be hard to use if the examples are out of date, but then again writing your own auth code is difficult too.

Java Api Login Issue [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am creating a API to allow end users to update my database.
I will put the API classes in a jar file and provide the jar to the user.
However I do want that the user should be authorised.(provide username and password)
Once the user has provided the user name and password do I have to check if user is logged in in every API call user is making?(I mean do I have to check in every getter and setter if user is logged in or not)?
Is their a different way?May be checking if user login credentials are correct or not?if not then destroying the object created?
EDIT
API which will be in jar file
import package org.atul.module.registration;
public class HelloWorld(){
private bool isLogin=false;
private String userName="user";
private String Password="password";
public HelloWorld(String userName,String password){
isLogin = checkAuthentication(userName,password); //will make true if creadential are correct
}
public String getInformation(){
//return Information from database
}
//other getters and setters
As I cant stop user from creating an object Do I have to check isLogin is true in every function(getter and seter) I make?
I will give you a solution, may be is not the best but can help you. The intent is that you only can create objects with factories, so there you ask for user and pass. If you want you can make a cache of users logged in the superfactory to check if is it logged or not. I made you a simple diagram
create objects with the factory, register the user, throws an exception if doesn't exist pass and user.
In interface you declare methods that you want client use.
Constructor access level for classes is package. So your clients can't access them only with factories.
Another thing you can implements is like an Interceptor each request client gives you, pass to a class that check if is it logged the user.

Categories