Handling CuratorFramework close method properly - apache-zookeeper

I'm receiving a stack trace in log files when testing my ZooKeeperFetcher class. I'm quite sure that the problem lies in the fact
that CuratorFramework client is being closed before the pathChildrenCache instance. Is it possible for pathChildrenCache to detect and
call close() once curatorFramework was closed? I cannot simply add new close() -> {pathChildrenCache.close(); } method to ZooKeeperFetcher.
Simplified code:
public class ZooKeeperFetcher() {
private final CuratorFramework client;
private PathChildrenCache pathChildrenCache;
ZooKeeperFetcher(CuratorFramework client) {
this.client = client;
pathChildrenCache = new PathChildrenCache(client, '/', true);
PathChildrenCacheListener pathListener =
(client, event) -> /* handle event */;
}
/* this option is just not possible for me */
// public void close() {
// pathChildrenCache.close();
// }
}
And the test class:
public class TestZooKeeperFetcher {
private TestingServer zookeeperServer;
private final CuratorFramework client;
private ZooKeeperFetcher fetcher;
#Before
public void beforeEachTest() {
zookeeperServer = new TestingServer(true);
client =
CuratorFrameworkFactory.newClient(
zookeeperServer.getConnectString(), new RetryNTimes(10, 50));
client.start();
fetcher = ZooKeeperFetcher(client);
}
#After
public void afterEachTest() throws Exception {
client.close();
}
#Test
public void justDontThrowExceptionsTest() throws Exception {
}
}

Related

Dynamic Merge of Infinite Reactor streams

Usecase:
There is a module which Listens for events in synchronous mode. In the same module using the EmitterProccessor, the event is converted to Flux and made as infinite stream of events. Now there is a upstream module which can subscribes for these event streams. The problem here is how can I dynamically merge these streams to one and then subscribe in a single stream. A simple example is, let us say there are N number of sensors, we can dynamically register these sensors and start listening for measurements as stream of data in single stream after merging them into one stream. Here is the code sample written to mock this behavior.
Create callback and start listening for events
public interface CallBack {
void callBack(int name);
void done();
}
#Slf4j
#RequiredArgsConstructor
public class CallBackService {
private CallBack callBack;
private final Function<Integer, Integer> func;
public void register(CallBack intf) {
this.callBack = intf;
}
public void startServer() {
log.info("Callback started..");
IntStream.range(0, 10).forEach(i -> {
callBack.callBack(func.apply(i));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
log.info("Callback finished..");
callBack.done();
}
}
Convert the events to streams using event proccessor
#Slf4j
public class EmitterService implements CallBack {
private EmitterProcessor<Integer> emitterProcessor;
public EmitterService(){
emitterProcessor = EmitterProcessor.create();
}
public EmitterProcessor<Integer> getEmmitor() {
return emitterProcessor;
}
#Override
public void callBack(int name) {
log.info("callbakc {} invoked", name);
//fluxSink.next(name);
emitterProcessor.onNext(name);
}
public void done() {
//fluxSink.complete();
emitterProcessor.onComplete();
}
}
public class WrapperService {
EmitterService service1;
ExecutorService service2;
public Flux<Integer> startService(Function<Integer, Integer> func) {
CallBackService service = new CallBackService(func);
service1 = new EmitterService();
service.register(service1);
service2 = Executors.newSingleThreadExecutor();
service2.submit(service::startServer);
return service1.getEmmitor();
}
public void shutDown() {
service1.getEmmitor().onComplete();
service2.shutdown();
}
}
Subscribe for the events
#Slf4j
public class MainService {
public static void main(String[] args) throws InterruptedException {
TopicProcessor<Integer> stealer = TopicProcessor.<Integer>builder().share(true).build();
CountDownLatch latch = new CountDownLatch(20);
WrapperService n1 =new WrapperService();
WrapperService n2 =new WrapperService();
// n1.startService(i->i).mergeWith(n2.startService(i->i*2)).subscribe(stealer);
n1.startService(i->i).subscribe(stealer);
n2.startService(i->i*2).subscribe(stealer);
stealer.subscribeOn(Schedulers.boundedElastic())
.subscribe(x->{
log.info("Stole=>{}", x);
latch.countDown();
log.info("Latch count=>{}", latch.getCount());
});
latch.await();
n1.shutDown();
n2.shutDown();
stealer.shutdown();
}
}
Tried to use TopicProccessor with no success. In the above code subscription happens for first source, for second source there is no subscription. however if use n1.startService(i->i).mergeWith(n2.startService(i->i*2)).subscribe(stealer); subscription works, but there is no dynamic behavior in this case. Need to change subscriber every time.

Connection leakage issue when static method called from spring transactional method

I have a transactional method at Service layer which call a static method where i am starting a thread for some async task(again some database operation). Does calling a static method from transactional scope can make some db connection leakage problem ?
Below is a sample code explaining the use case.
#Override
#Transactional
public void createRecords(Record r1, Record r2, HttpServletRequest request) {
saveSomeData(r1,r2.getScore());
// Call a Static Method that open a seperate thread
AsyncTasker.doSomeThing(r2);
saveNewData(r2);
}
AsyncTasker.java
public class AsyncTasker {
private static final Logger logger = LoggerFactory.getLogger(AsyncTasker.class);
private static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void doSomeThing(Record r){
try{
ClearTask clearTask = new ClearTask(r);
executorService.submit(clearTask);
}
catch(Exception e){
logger.error("Error in ClearTask task execution " + r +" : Exception "+ e);
}
}
}
class ClearTask implements Runnable{
private Record r;
ClearTask(Record r){
this.r = r;
}
#Override`enter code here`
public void run() {
Token.deleteAllData(r); // Static method making a rest call
}
}

Handling multiple client in java

I made simple client server chat program that support multiple client but i have a problem:`
public class Main extends Application {
public Button send;
public TextArea textarea;
public TextArea onlineuser;
public TextField usertext;
public static int maxUser = 100;
public boolean run=true;
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("server.fxml"));
primaryStage.setTitle("Server control ");
primaryStage.setScene(new Scene(root, 749, 494));
primaryStage.show();
}
public static void main(String[] args) throws IOException{
Server sv=new Server(1111);
launch(args);
}
class Server extends Thread {
private ServerSocket sv;
private ThreadServer[] clientconnect = new ThreadServer[maxUser];
public Server(int port) throws IOException {
this.sv = new ServerSocket(port);
start();
}
public void run() {
while (run) {
try {
Socket connect = this.sv.accept();
connectionThread(connect);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void connectionThread(Socket connection) {
for (int a = 0; a < maxUser; a++) {
if (this.clientconnect[a] == null) {
this.clientconnect[a] = new ThreadServer(connection, a);
break;
}
}
}
}
class ThreadServer extends Thread {
final private int userID;
final private Socket threadconnect;
public void run() {
while (run)) {
try {
PrintWriter out = new PrintWriter(threadconnect.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(threadconnect.getInputStream()));
textarea.appendText(in.readLine());
out.println(usertext.getText());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public ThreadServer(Socket connect, int ID) {
this.userID = ID;
this.threadconnect = connect;
}
}
I have client part works fine but i cant call my server class in main because it's not a static but i should use main also launch javafx gui part how can i solve this problem?

How to use same servlet for RPC and upload File in GWT.

i created a web application where i have to use fileUpload.
i have to send the file and their properties to server . For sending a file i used FormPanel and for properties i used RPC .
public void onModuleLoad() {
final FileServiceEndPoint serviceEndPoint = new FileServiceEndPoint();
new AddDocument();
Button b = new Button("addDocument");
b.addClickHandler(new ClickHandler() {
private Map<String, String> docProperty;
public void onClick(ClickEvent event) {
docProperty =getProperties();
AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onSuccess(String result) {
System.out.println("he ha" +result);
}
public void onFailure(Throwable caught) {
}
};
serviceEndPoint.uploadAttachement(docProperty, callback);
}
});
RootPanel.get().add(b);
}
this new AddDocument(); contains code for uploading a file (formPanel code)
private FormPanel getFormPanel() {
if (uploadForm == null) {
uploadForm = new FormPanel();
uploadForm.setAction(GWT.getHostPageBaseURL() +"TestUploadFileServlet");
uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART);
uploadForm.setMethod(FormPanel.METHOD_POST);
uploadForm.setWidget(getFileUpload());
System.out.println(GWT.getHostPageBaseURL() +"TestUploadFileServlet");
uploadForm.addFormHandler(new FormHandler() {
public void onSubmitComplete(FormSubmitCompleteEvent event) {
AddDocument.this.hide(true);
}
public void onSubmit(FormSubmitEvent event) {
}
});
}
return uploadForm;
}
private Button getAddButton() {
if (addButton == null) {
addButton = new Button("ADD");
addButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
uploadForm.submit();
}
});
addButton.setText("Add");
}
Interface is created for Sending property.
EndPoints:
public class FileServiceEndPoint implements FileServiceAsync{
FileServiceAsync service = (FileServiceAsync)GWT.create(FileService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) service;
public FileServiceEndPoint() {
endpoint.setServiceEntryPoint(GWT.getHostPageBaseURL() + “TestUploadFileServlet”);
}
public void uploadAttachement(Map docProperty,
AsyncCallback callback) {
service.uploadAttachement(docProperty, callback);
}
}
On Server:
public class FileUploadImpl extends RemoteServiceServlet implements FileService {
private static final long serialVersionUID = 1L;
private static final Logger log = Logger.getLogger(FileUploadImpl.class
.getName());
String a;
protected void service(final HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException {
a=”5″;
System.out.println(“ServletWorking Fine “);
}
public String uploadAttachement(Map docProperty) {
// TODO Auto-generated method stub
return “Checked”;
}
}
When I debug formPanel.submit : the debugger goes in Server and print ServletWorking Fine(this is perfect)
and when i debug the addProperties button it goes to server and print ServletWorking Fine. but It should not go in service method.
the debugger should go in UploadAttachement.
Plz tell how to pass hashMap using same servlet.

GWT Void remote services fail for seemingly no reason

I'm working on a GWT project and have several void remote services that seem to execute just fine, but on the client side, end up firing the onFailure() method. No exceptions are thrown anywhere, and the expected behavior is observed on the backend. I have no idea what could be going wrong. Here is the relevant code:
Interfaces and implementation...
#RemoteServiceRelativePath("DeleteSearchService")
public interface DeleteSearchService extends RemoteService {
/**
* Utility class for simplifying access to the instance of async service.
*/
public static class Util {
private static DeleteSearchServiceAsync instance;
public static DeleteSearchServiceAsync getInstance(){
if (instance == null) {
instance = GWT.create(DeleteSearchService.class);
}
return instance;
}
}
public void delete(SearchBean search);
}
public interface DeleteSearchServiceAsync {
public void delete(SearchBean bean, AsyncCallback<Void> callback);
}
public class DeleteSearchServiceImpl extends RemoteServiceServlet implements DeleteSearchService {
private static final long serialVersionUID = 1L;
#Override
public void delete(SearchBean search) {
try {
Connection conn = SQLAccess.getConnection();
String sql = "DELETE FROM `searches` WHERE `id`=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, search.getSearchId());
ps.execute();
sql = "DELETE FROM `searchsourcemap` WHERE `search-id` = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, search.getSearchId());
ps.execute();
return;
} catch (Exception e) {
// TODO Log error
e.printStackTrace();
}
}
}
Calling code...
private class DeleteListener implements ClickListener {
public void onClick(Widget sender) {
DeleteSearchServiceAsync dss = DeleteSearchService.Util.getInstance();
SearchBean bean = buildBeanFromGUI();
dss.delete(bean, new AsyncCallback<Void>(){
//#Override
public void onFailure(Throwable caught) {
// TODO log
SearchNotDeleted snd = new SearchNotDeleted();
snd.show();
}
//#Override
public void onSuccess(Void result) {
SearchDeleted sd = new SearchDeleted();
sd.show();
searchDef.getParent().removeFromParent();
}
});
}
}
I know I'm a jerk for posting like 500 lines of code but I've been staring at this since yesterday and can't figure out where I'm going wrong. Maybe a 2nd set of eyes would help...
Thanks,
brian
LGTM I'm afraid.
Are you using the hosted mode or a full-fledged browser? You can try switching and see if it helps.
Also, it might help listening to that //TODO and perform a GWT.log when onFailure is invoked.