Commit 87f2dfc2 authored by abdullh.alsoleman's avatar abdullh.alsoleman

initial

parent 1a40c114
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
<component name="ArtifactManager">
<artifact type="jar" name="registration-and-discovery-zookeeper-master-with-autohealer:jar">
<output-path>$PROJECT_DIR$/out/artifacts/registration_and_discovery_zookeeper_master_with_autohealer_jar</output-path>
<root id="archive" name="registration-and-discovery-zookeeper-master-with-autohealer.jar">
<element id="module-output" name="registration-and-discovery-zookeeper-master-with-autohealer" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-buffer/4.1.94.Final/netty-buffer-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-resolver/4.1.94.Final/netty-resolver-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-native-unix-common/4.1.94.Final/netty-transport-native-unix-common-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/yetus/audience-annotations/0.12.0/audience-annotations-0.12.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-codec/4.1.94.Final/netty-codec-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-boringssl-static/2.0.61.Final/netty-tcnative-boringssl-static-2.0.61.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/ch/qos/logback/logback-classic/1.2.10/logback-classic-1.2.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-boringssl-static/2.0.61.Final/netty-tcnative-boringssl-static-2.0.61.Final-osx-aarch_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-boringssl-static/2.0.61.Final/netty-tcnative-boringssl-static-2.0.61.Final-linux-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-boringssl-static/2.0.61.Final/netty-tcnative-boringssl-static-2.0.61.Final-osx-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-boringssl-static/2.0.61.Final/netty-tcnative-boringssl-static-2.0.61.Final-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/zookeeper/zookeeper-jute/3.9.1/zookeeper-jute-3.9.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-common/4.1.94.Final/netty-common-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-classes-epoll/4.1.94.Final/netty-transport-classes-epoll-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/ch/qos/logback/logback-core/1.2.10/logback-core-1.2.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-boringssl-static/2.0.61.Final/netty-tcnative-boringssl-static-2.0.61.Final-linux-aarch_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport/4.1.94.Final/netty-transport-4.1.94.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-native-epoll/4.1.94.Final/netty-transport-native-epoll-4.1.94.Final-linux-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/zookeeper/zookeeper/3.9.1/zookeeper-3.9.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-tcnative-classes/2.0.61.Final/netty-tcnative-classes-2.0.61.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-handler/4.1.94.Final/netty-handler-4.1.94.Final.jar" path-in-jar="/" />
</root>
</artifact>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17 (2)" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ArtifactsWorkspaceSettings">
<artifacts-to-build>
<artifact name="registration-and-discovery-zookeeper-master-with-autohealer:jar" />
</artifacts-to-build>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="077b7c43-97db-4c44-8c3b-4db2bcdbd712" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/artifacts/registration_and_discovery_zookeeper_master_with_autohealer_jar.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/encodings.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/uiDesigner.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/Application.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/Autohealer.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/LeaderElection.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/OnElectionAction.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/OnElectionCallback.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/ServiceRegistry.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/Zookeeper/Worker.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/resources/META-INF/MANIFEST.MF" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/resources/logback.xml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="2anp4i2gQJWodmppXPCuq6yy4zd" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_ADD_EXTERNAL_FILES": "true",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"last_opened_file_path": "E:/fifth year/registration-and-discovery-zookeeper-master-with-autohealer",
"project.structure.last.edited": "Artifacts",
"project.structure.proportion": "0.0",
"project.structure.side.proportion": "0.0"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="E:\fifth year\registration-and-discovery-zookeeper-master-with-autohealer\src\main\java" />
<recent name="E:\fifth year\registration-and-discovery-zookeeper-master-with-autohealer\src\main\resources" />
</key>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="077b7c43-97db-4c44-8c3b-4db2bcdbd712" name="Changes" comment="" />
<created>1704964011809</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1704964011809</updated>
</task>
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
</component>
</project>
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Service-Registration-and-Discovery</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.9.1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package Zookeeper;
import ch.qos.logback.classic.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class Application implements Watcher {
private static final Logger logger = (Logger) LoggerFactory.getLogger(Application.class);
private static final String address = "192.168.56.115:2181";
private static final int SESSION_TIMEOUT = 3000; //dead client
private static final int DEFAULT_PORT = 8080;
private ZooKeeper zooKeeper;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
if (args.length != 3) {
logger.error("Expecting parameters <port number> <number of workers> <path to worker jar file>");
System.exit(1);
}
int currentServerPort = args.length == 1 ? Integer.parseInt(args[0]) : DEFAULT_PORT;
Application application = new Application();
ZooKeeper zooKeeper = application.connectToZookeeper();
int numberOfWorkers = Integer.parseInt(args[1]);
String pathToWorkerProgram = args[2];
Autohealer autohealer = new Autohealer(numberOfWorkers, pathToWorkerProgram,zooKeeper);
ServiceRegistry serviceRegistry = new ServiceRegistry(zooKeeper,autohealer);
OnElectionAction onElectionAction = new OnElectionAction(serviceRegistry, currentServerPort);
LeaderElection leaderElection = new LeaderElection(zooKeeper, onElectionAction);
leaderElection.volunteerForLeadership();
leaderElection.reelectLeader();
application.run();
application.close();
}
public ZooKeeper connectToZookeeper() throws IOException {
this.zooKeeper = new ZooKeeper(address, SESSION_TIMEOUT, this);
return zooKeeper;
}
public void run() throws InterruptedException {
synchronized (zooKeeper) {
zooKeeper.wait();
}
}
private void close() throws InterruptedException {
this.zooKeeper.close();
}
@Override
public void process(WatchedEvent watchedEvent) {
switch (watchedEvent.getType()) {
case None:
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
logger.info("Successfully connected to Zookeeper");
} else if (watchedEvent.getState() == Event.KeeperState.Disconnected) {
synchronized (zooKeeper) {
logger.error("Disconnected from Zookeeper");
zooKeeper.notifyAll();
}
} else if (watchedEvent.getState() == Event.KeeperState.Closed) {
logger.error ("Closed Successfully");
}
break;
}
}
}
package Zookeeper;/*
* MIT License
*
* Copyright (c) 2019 Michael Pogrebinsky - Distributed Systems & Cloud Computing with Java
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import ch.qos.logback.classic.Logger;
import org.apache.zookeeper.*;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class Autohealer implements Watcher {
private static final String REGISTRY_ZNODE = "/service_registry";
// Parent Znode where each worker stores an ephemeral child to indicate it is alive
private static final String AUTOHEALER_ZNODES_PATH = "/workers";
// Path to the worker jar
private final String pathToProgram;
// The number of worker instances we need to maintain at all times
private final int numberOfWorkers;
private ZooKeeper zooKeeper;
private static final Logger logger = (Logger) LoggerFactory.getLogger(Autohealer.class);
public Autohealer(int numberOfWorkers, String pathToProgram, ZooKeeper zooKeeper) {
this.zooKeeper = zooKeeper;
this.numberOfWorkers = numberOfWorkers;
this.pathToProgram = pathToProgram;
}
public void startWatchingWorkers() throws KeeperException, InterruptedException {
System.out.println("start watching");
if (zooKeeper.exists(AUTOHEALER_ZNODES_PATH, false) == null) {
zooKeeper.create(AUTOHEALER_ZNODES_PATH, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
launchWorkersIfNecessary();
}
public synchronized void launchWorkersIfNecessary() throws InterruptedException {
Thread.sleep(15000);
logger.info("start launch");
try {
// Check if the parent znode exists, create it if not
if (zooKeeper.exists(AUTOHEALER_ZNODES_PATH, false) == null) {
zooKeeper.create(AUTOHEALER_ZNODES_PATH, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
// Get the current number of workers
List<String> Jobs = zooKeeper.getChildren(AUTOHEALER_ZNODES_PATH, this);
for (String job : Jobs) {
zooKeeper.exists(AUTOHEALER_ZNODES_PATH + "/" + job, this);
}
int currentJobs = Jobs.size();
logger.info("Number of jobs is {}" , numberOfWorkers);
if (ServiceRegistry.getWorkers() == null)
return;
for (Worker worker : ServiceRegistry.getWorkers()) {
worker.setnumOfJobsZero();
}
for (String job : Jobs) {
String[] parts = job.split("'");
// Extract workerNode using Substring
Worker worker = Worker.findByNodeName(parts[1], ServiceRegistry.getWorkers());
worker.increaseOne();
}
Worker.SortNodes(ServiceRegistry.getWorkers());
while (true) {
List<Worker> workers = ServiceRegistry.getWorkers();
for (Worker worker : workers) {
logger.info("Total number of job {}",Worker.getTotalNumOfJob(workers));
Thread.sleep(2000);
if (Worker.getTotalNumOfJob(workers) < numberOfWorkers) {
startJobOnNode(worker);
currentJobs++;
} else break;
}
if (Worker.getTotalNumOfJob(workers) >= numberOfWorkers) break;
}
} catch (KeeperException | InterruptedException | IOException e) {
e.printStackTrace();
}
}
private synchronized void startJobOnNode(Worker worker) throws IOException, InterruptedException, KeeperException {
logger.info("start job at {} " , worker.getIpAddress());
// Start a new worker instance on the specified node
File file = new File(pathToProgram);
String remoteDirectory = "/home/" + worker.getUserName() + "/";
String remoteJarFilePath = remoteDirectory + file.getName();
String userName = worker.getUserName();
String nodeName = worker.getNodeName();
String ip = worker.getIpAddress();
// SCP command to copy the JAR file to the remote machine
String scpCommand = "scp " + pathToProgram + " " +
userName + "@" + ip + ":" + remoteDirectory;
// SSH command to execute the JAR file remotely
String sshCommand = "ssh " + userName + "@" + ip +
" java -jar " + remoteJarFilePath + " " + nodeName;
logger.info("first command: " + scpCommand);
// Execute SCP command to copy the JAR file
Process scpProcess = Runtime.getRuntime().exec(scpCommand);
scpProcess.waitFor();
// Check if SCP was successful before executing the JAR remotely
if (scpProcess.exitValue() == 0) {
logger.info("second command: " + sshCommand);
// Execute SSH command to run the JAR file remotely
Process sshProcess = Runtime.getRuntime().exec(sshCommand);
worker.increaseOne();
logger.info("The number of job on " + worker.getNodeName() + " is " + worker.getJobsNum());
}
}
private void restartJobOnSameNode(Worker worker) throws IOException, InterruptedException, KeeperException {
}
@Override
public void process(WatchedEvent event) {
switch (event.getType()) {
case NodeDeleted:
// Handle changes in the child nodes of the watched znode (e.g., workers added or removed)
logger.info("Job nodes deleted in " + event.getPath());
String fullPath = event.getPath();
String[] parts = fullPath.split("'");
// Extract workerNode using Substring
String workerNode = parts[1];
if (event.getType() == Event.EventType.NodeDeleted)
try {
launchWorkersIfNecessary();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
break;
default:
List<String> jobs = null;
try {
jobs = zooKeeper.getChildren(AUTOHEALER_ZNODES_PATH, false);
for (String job : jobs) {
zooKeeper.exists(AUTOHEALER_ZNODES_PATH + "/" + job, this);
}
} catch (KeeperException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
break;
}
}
}
package Zookeeper;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.util.Collections;
import java.util.List;
public class LeaderElection implements Watcher {
private static final String ELECTION_NAMESPACE = "/election";
private String currentZnodeName;
private ZooKeeper zooKeeper;
private OnElectionCallback onElectionCallback;
public LeaderElection(ZooKeeper zooKeeper, OnElectionCallback onElectionCallback) {
this.zooKeeper = zooKeeper;
this.onElectionCallback = onElectionCallback;
}
public void volunteerForLeadership() throws InterruptedException, KeeperException {
String znodePrefix = ELECTION_NAMESPACE + "/c_";
String znodeFullPath = zooKeeper.create(znodePrefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(znodeFullPath);
this.currentZnodeName = znodeFullPath.replace(ELECTION_NAMESPACE + "/", "");
}
public void reelectLeader() throws InterruptedException, KeeperException {
String predecessorName = "";
Stat predecessorStat = null;
//this while to guarantee get predecessor even if it deleted just before zookeeper.exist
while (predecessorStat == null) {
List<String> children = zooKeeper.getChildren(ELECTION_NAMESPACE, false);
Collections.sort(children);
String smallestChild = children.get(0); //the first element
if (smallestChild.equals(currentZnodeName)) {
System.out.println("I'm a leader");
onElectionCallback.onElectedToBeLeader();
return;
} else {
System.out.println("I'm not a leader");
int predecessorIndex = children.indexOf(currentZnodeName) - 1;
predecessorName = children.get(predecessorIndex);
predecessorStat = zooKeeper.exists(ELECTION_NAMESPACE + "/" + predecessorName, this);
}
}
onElectionCallback.onWorker();
System.out.println("Watching znode " + predecessorName);
System.out.println();
}
@Override
public void process(WatchedEvent watchedEvent) {
switch (watchedEvent.getType()) {
case NodeDeleted:
try {
reelectLeader();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (KeeperException e) {
throw new RuntimeException(e);
}
break;
}
}
}
package Zookeeper;
import org.apache.zookeeper.KeeperException;
public class OnElectionAction implements OnElectionCallback {
private final ServiceRegistry serviceRegistry;
private final int port;
public OnElectionAction(ServiceRegistry serviceRegistry, int port) {
this.serviceRegistry = serviceRegistry;
this.port = port;
}
@Override
public void onElectedToBeLeader() throws InterruptedException, KeeperException {
serviceRegistry.unregisterFromCluster();
serviceRegistry.registerForUpdates();
}
@Override
public void onWorker() {
try {
String username = System.getProperty("user.name");
String currentServerAddress =
"192.168.56.116"+","+username+"," +port;
serviceRegistry.registerToCluster(currentServerAddress);
} catch (InterruptedException e) {
e.printStackTrace();
}catch (KeeperException e) {
e.printStackTrace();
}
}
}
package Zookeeper;
import org.apache.zookeeper.KeeperException;
public interface OnElectionCallback {
void onElectedToBeLeader() throws InterruptedException, KeeperException;
void onWorker();
}
package Zookeeper;
import ch.qos.logback.classic.Logger;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class ServiceRegistry implements Watcher {
private static final String REGISTRY_ZNODE = "/service_registry";
private final ZooKeeper zooKeeper;
private String currentZnode = null;
private static final Logger logger = (Logger) LoggerFactory.getLogger(ServiceRegistry.class);
private static List<Worker> workers= new ArrayList<>();
private Autohealer autohealer;
public ServiceRegistry(ZooKeeper zooKeeper, Autohealer autohealer) {
this.autohealer=autohealer;
this.zooKeeper = zooKeeper;
createServiceRegistryZnode();
}
private void createServiceRegistryZnode() {
try {
if (zooKeeper.exists(REGISTRY_ZNODE, false) == null) {
zooKeeper.create(REGISTRY_ZNODE, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void registerToCluster(String metadata) throws KeeperException, InterruptedException {
if (this.currentZnode != null) {
logger.info("Already registered to service registry");
return;
}
this.currentZnode = zooKeeper.create(REGISTRY_ZNODE + "/n_", metadata.getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
logger.info("Registered to service registry");
}
public void registerForUpdates() {
try {
updateAddresses();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void unregisterFromCluster() {
try {
if (currentZnode != null && zooKeeper.exists(currentZnode, false) != null) {
zooKeeper.delete(currentZnode, -1);
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private synchronized void updateAddresses() throws KeeperException, InterruptedException {
System.out.println("Enter");
List<String> workerZnodes = zooKeeper.getChildren(REGISTRY_ZNODE, this);
// SortNodes(workerZnodes);
// List<String> addresses = new ArrayList<>();
// List<String> names = new ArrayList<>();
List<Worker> workerList= new ArrayList<>();
Thread.sleep(100);
for (String workerZnode : workerZnodes) {
String workerFullPath = REGISTRY_ZNODE + "/" + workerZnode;
Worker newWorker = new Worker(workerZnode);
Stat stat = zooKeeper.exists(workerFullPath, false);
if (stat == null) {
continue;
}
byte[] addressBytes = zooKeeper.getData(workerFullPath, false, stat);
String data = new String(addressBytes);
String[] parts = data.split(",");
String address = parts[0];
newWorker.setIpAddress(address);
newWorker.setUserName(parts[1]);
workerList.add(newWorker);
}
Worker.SortNodes(workerList);
System.out.println(workers);
if(workers!=null)
workers.removeAll(workers);
if(workerList!=null)
workers.addAll(workerList);
logger.info("The cluster addresses are: " + Worker.getIpAddress(workers));
}
@Override
public void process(WatchedEvent watchedEvent) {
try {
updateAddresses();
System.out.println(workers);
Thread.sleep(1000);
if(workers!=null)
autohealer.startWatchingWorkers();
} catch (KeeperException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public static List<Worker> getWorkers() {
return workers;
}
}
\ No newline at end of file
package Zookeeper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Worker {
private String nodeName;
private String ipAddress;
private String userName;
private int JobsNum=0;
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Worker(String fullPathNode) {
this.nodeName = fullPathNode;
}
public String getNodeName() {
return nodeName;
}
public int getJobsNum() {
return JobsNum;
}
public synchronized void increaseOne(){
JobsNum++;
}
public static List<String> getIpAddress(List<Worker> workers){
List<String> allAddress= new ArrayList<>();
for (Worker worker:workers) {
allAddress.add(worker.ipAddress);
}
return allAddress;
}
public String getIpAddress() {
return ipAddress;
}
public String getUserName() {
return userName;
}
public static void SortNodes(List<Worker> workers) {
// Custom comparator to sort based on the size of the JobsNode list
Comparator<Worker> byJobsListSize = Comparator.comparingInt(worker -> worker.getJobsNum());
// Sorting the list using the custom comparator
Collections.sort(workers, byJobsListSize);
}
public static Worker findByNodeName(String nodeName, List<Worker> workers){
for (Worker worker:workers) {
if(worker.getNodeName().equals(nodeName)) {
return worker;
}
}
return null;
}
public void setnumOfJobsZero() {
JobsNum=0;
}
public static int getTotalNumOfJob(List<Worker> workers){
int sum=0;
for (Worker worker:workers) {
sum+=worker.JobsNum;
}
return sum;
}
}
Manifest-Version: 1.0
Main-Class: Zookeeper.Application
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="HOME_LOG" value="logs/app.log"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${HOME_LOG}</file>
<append>true</append>
<immediateFlush>true</immediateFlush>
<encoder>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</encoder>
</appender>
<!-- Log Level: ERROR, WARN, INFO, DEBUG, TRACE-->
<logger name="Zookeeper" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
<root level="error">
<appender-ref ref="FILE"/>
</root>
</configuration>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment