I'm developing a web application that needs to communicate with any servers (python) by socket. My web application will be the client socket.
I read some alternatives about EJB and Socket. (JCA was indicated, but it is too much for my simple client)
To simplify the solution I was thinking to create an EJB #Singleton and create Threads to work in it.
Do you have some suggestion?
My simple idea:
Singleton
#Startup
#Singleton
public class SingletonBean {
private List<EventMonitor> monitors = new ArrayList<>();
#PostConstruct
private void postConstruct() {
EventMonitor monitor = new EventMonitor("192.168.1.1", 23);
monitors.add(monitor);
monitor.start();
monitor = new EventMonitor("192.168.1.2", 23);
monitors.add(monitor);
monitor.start();
}
}
Monitor
public class EventMonitor extends Thread {
private String host;
private int port;
public EventMonitor(final String host, final int port) {
this.host = host;
this.port = port;
openConnection();
}
#Override
public void run() {
// read socket message and persist
// I think persist here is not a good idea, any better idea?
}
}
Any suggestion?
Thank you for your time.
By the way, the answer was simple like the idea!
Singleton was enough in this case.
Related
The application is based on the following stack:
Quarkus 1.5.0
Extensions: vertx-web, reactive-pgclient
The complete codes is here.
I created a Router by #Observes Router.
#ApplicationScoped
public class RoutesObserver {
#Inject PostsHandlers handlers;
public void route(#Observes Router router) {
router.get("/posts").produces("application/json").handler(handlers::getAll);
router.post("/posts").consumes("application/json").handler(handlers::save);
router.get("/posts/:id").produces("application/json").handler(handlers::get);
router.put("/posts/:id").consumes("application/json").handler(handlers::update);
router.delete("/posts/:id").handler(handlers::delete);
router.get("/hello").handler(rc -> rc.response().end("Hello from my route"));
}
}
And extracted the handlers into a standalone bean.
#ApplicationScoped
class PostsHandlers {
private static final Logger LOGGER = Logger.getLogger(PostsHandlers.class.getSimpleName());
PostRepository posts;
ObjectMapper objectMapper;
#Inject
public PostsHandlers(PostRepository posts, ObjectMapper objectMapper) {
this.posts = posts;
this.objectMapper = objectMapper;
}
public void getAll(RoutingContext rc) {
this.posts.findAll().thenAccept(
data -> rc.response()
.write(toJson(data))
.end()
);
}
//... other methods.
}
And the PostRepository used the Java 8 CompletionStage API.
#ApplicationScoped
public class PostRepository {
private static final Logger LOGGER = LoggerFactory.getLogger(PostRepository.class);
private final PgPool client;
#Inject
public PostRepository(PgPool _client) {
this.client = _client;
}
public CompletionStage<List<Post>> findAll() {
return client.query("SELECT * FROM posts ORDER BY id ASC")
.execute()
.thenApply(rs -> StreamSupport.stream(rs.spliterator(), false)
.map(this::from)
.collect(Collectors.toList())
);
}
And when I ran this application and tried to access the /posts. It is frozen and no response printed.
When using the write method, you need to set (beforehand) the content-length header.
There are a several approaches to handle this:
You can use .end(toJson(data)) instead of write(...).end() - it will computed the length automatically
You can use .putHeader("transfer-encoding", "chunked") and you write(...).end() - if you plan to retrieve multiple results, it's interesting as it writes each chunk to the client one by one, avoiding sending a large payload in one go
you can set the content-length as in:
String result = toJson(data);
rc.response()
.putHeader("content-length", Long.toString(result.length()))
.write(result)
.end();
I wrote an EJB scheduler that worked a few days ago, now it doesn't work.
I tried to delete the contents of the / wildfly / standalone / data / timer-service-data directory but the scheduler does not work.
This is the code of my EJB:
#Singleton
public class MyTimerService {
#Resource
private TimerService timerService;
/** The Constant logger. */
private static final Logger logger = Logger.getLogger(MyTimerService.class);
#PostConstruct
public void initialize() {
logger.info("MyTimerService initialization");
ScheduleExpression scheduleExpression = new ScheduleExpression().hour("*").minute( "*/5");
// Persistent must be set to false (since it defaults to true) because the timer is not specific to this JVM.
TimerConfig test = new TimerConfig("START TIMER", false);
timerService.createCalendarTimer(scheduleExpression, test);
}
#Timeout
public void scheduler(Timer timer) {
//my logic here ...
}
#PreDestroy
public void stop() {
logger.info("SingletonTimer is stopping: the server is either being shutdown or another node has become elected to be the singleton master.");
}
My code looks correct, maybe it's a server problem?
EDIT:
I added #Startup and now it works :)
Does anyone know how to open a JavaFx application via rest requests?
Scenario:
I have a Spring Boot Service that runs on every machine to make a bridge wiht my SPA(Single Page Application) and my comm ports. Thats because SPA cannot talk to the OS.
This communications are made via http requests.
Now I have a problem, I need to make a javafx application that is started via http request, when I call the firts time, it works ok, but if i close the javafx application clicking on 'x' and try to open again I'm getting the following error:
java.lang.IllegalStateException: Application launch must not be called more than once
There is a way that when I close the javafx window, it kill the JavaFx Thread, so when I call it again, it start a new Thread?
Or do I need to keep the Thread and just find a way to reopen my javafx application in the same Thread?
here is my #Controller
#RestController
#RequestMapping("v1/appfx")
public class AppfxController{
#RequestMapping("")
private void openJavaFxApp(){
try{
MyJavaFxApp.launch(MyJavaFxApp.class);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
And Here is my JavaFx:
public class MyJavaFxApp extends Application {
private final static Logger log = LoggerFactory.getLogger(MyJavaFxApp.class);
private BigDecimal left;
private String selectedOperator;
private boolean numberInputting;
#FXML
private TextField display;
public MyJavaFxApp() {
this.left = BigDecimal.ZERO;
this.selectedOperator = "";
this.numberInputting = false;
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("MyJavaFxApp");
stage.setOnCloseRequest(x -> {
log.info("closed");
Platform.exit();
});
stage.setResizable(false);
stage.setScene(new Scene(FXMLLoader.load(getClass().getClassLoader().getResource("Test.fxml"))));
stage.show();
stage.toFront();
}
}
Thanks for any help.
I'm trying to hook up a custom Ant listener to CometD, but I get an NPE where I expect a channel handle. Here's a code snippet:
#Service
public class CometListener implements BuildListener {
#Inject
private BayeuxServer bayeuxServer;
#Session
private LocalSession sender;
private String _channelName;
private ServerChannel _channel = null;
public CometListener() {
_channelName = "/my/test";
}
#PostConstruct
private void initChannel() {
_channel = bayeuxServer.createChannelIfAbsent(_channelName).getReference();
}
public final void buildFinished(final BuildEvent finish) {
// Convert the Update business object to a CometD-friendly format
Map<String, Object> data = new HashMap<String, Object>(4);
data.put("status", 1);
_channel.publish(sender, data);
finish.getProject().log("buildFinished() called.", Project.MSG_ERR);
}
}
I took Using cometd in dropwizard as an example, but the proposed answer didn't fix the problem there.
Thanks in advance for any feedback.
Nevermind, I need a Bayeux client here, not a server.
Note: I am not planning to use the Entity Framework as it does NOT support async queries.
I am unable to figure out which approach would be better for the following scenario with Dependency Injection and SQL Connection Pooling.
SQL Server Connection Pooling (ADO.NET) MSDN article recommends to use using (sqlConn) since I don't take a hit on connection.Open() and connection.Close() with Connection Pooling enabled.
Technique 1:
Inject a SqlConnection dependency into my CustomerRepository class.
Use an instance per HTTP Request for the SqlConnection.
Call connection.Open() before it is injected into the CustomerRepository class.
Technique 2:
Only inject the Connection String into my CustomerRepository class.
Initialize using (SqlConnection) blocks in each of my CRUD methods?
Additional Things to Consider
I will be using async calls with my SqlCommand.BeginExecuteReader() for some SQL queries that takes about 2-4 seconds to execute.
In some special scenarios, I need to run 2-or-more parallel SQL query calls as well.
Please also keep in mind how the two techniques affect the coding style for IDisposable and using (connection) stuff.
Questions
Are there any differences between the two approaches given the fact that Connection Pooling is enabled?
Which technique should I use and why?
Code Sample for Technique 1:
// ------------------------------------------------------------
// Autofac Dependency Injection setup
// ------------------------------------------------------------
ContainerBuilder builder = new ContainerBuilder();
builder.Register(
c => {
var conn = new SqlConnection( "connectionString" );
conn.Open(); // open the connection ahead of time before injecting it into my CustomerRepository
return conn;
})
.Named("myNamedConnection", typeof(SqlConnection))
.InstancePerHttpRequest();
builder.Register(
c => {
new CustomerRepository(c.ResolveNamed<SqlConnection>("myNamedConnection")))
})
.As<ICustomerRepository>();
// ------------------------------------------------------------
// CustomerRepository
// ------------------------------------------------------------
public class CustomerRepository : ICustomerRepository, IDisposable
{
private SqlConnection conn;
private bool disposed;
public CustomerRepository(SqlConnection connection)
{
conn = connection;
disposed = false;
}
public Customer GetById(int id)
{
using (var cmd = conn.CreateCommand())
{
// code to retrieve Customer by id
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (conn != null)
{
conn.Dispose();
conn = null;
}
}
disposed = true;
}
}
}
Code Sample for Technique 2:
// ------------------------------------------------------------
// CustomerRepository
// ------------------------------------------------------------
public class CustomerRepository : ICustomerRepository
{
private readonly string strConn;
public CustomerRepository(string strConnection) // strConnection has Connection Pooling enabled
{
strConn = strConnection;
}
public Customer GetById(int id)
{
using (var conn = new SqlConnection(this.strConn))
{
using (var cmd = conn.CreateCommand())
{
// code to retrieve Customer by id
}
}
}
}
Thanks in advance for any thoughtful inputs :-)
Don't go for technique 1. Leaving the connection open for the complete request is not adviced: it should be closed as soon as possible, so don't leave it open for the complete request.
Don't go for technique 2. Injecting a connection string in each and every repository is cumbersome and if you are doing that, it seems to me that you are missing an abstraction, in your code. You probably don't want every repository create a new SqlConnection by itself.
You might be better of by injecting an IDatabase abstraction of some sort into your repositories. You can inject the connection string in your IDatabase implementation. This abstraction can have a BeginExecuteReader method or perhaps even some higher level abstraction.