Skip to content

Commit

Permalink
most code for headless property and disallow startup when memory too low
Browse files Browse the repository at this point in the history
  • Loading branch information
eostermueller committed Feb 1, 2023
1 parent e1bb98c commit d09e9c8
Show file tree
Hide file tree
Showing 59 changed files with 2,903 additions and 116 deletions.
220 changes: 220 additions & 0 deletions backend/out.txt

Large diffs are not rendered by default.

49 changes: 38 additions & 11 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<spring.version>2.4.5</spring.version>
<jackson.version>2.14.2</jackson.version>
</properties>
<parent>
<groupId>com.github.eostermueller</groupId>
<artifactId>SpringBootAngularApp</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
</parent>

<profiles>
Expand Down Expand Up @@ -43,7 +44,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
</profiles>

<artifactId>load-test-in-a-box_agent</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -85,24 +86,50 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
<version>${spring.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.eostermueller</groupId>
<artifactId>frontend</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>6.2.0.202206071550-r</version>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>1.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.13.1.202206130422-r</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-patch</artifactId>
<version>1.13</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-autoconfigure
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public interface Context {
public void setConfiguration(Configuration cfg);
public Logger getLogger();
public Factory getFactory() throws CannotFindSnail4jFactoryClass;
public NonPersistentParameters getNonPersistentParameters() throws CannotFindSnail4jFactoryClass;
public Messages getMessages() throws CannotFindSnail4jFactoryClass;

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ public Logger getLogger() {
return LOGGER;
}
@Override
public NonPersistentParameters getNonPersistentParameters() throws CannotFindSnail4jFactoryClass {
return DefaultFactory.getFactory().getNonPersistentParameters();
}
@Override
public Messages getMessages() throws CannotFindSnail4jFactoryClass {
return DefaultFactory.getFactory().createMessages();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;

import com.github.eostermueller.snail4j.config.DefaultGenericConfigFileReaderWriter;
import com.github.eostermueller.snail4j.config.GenericConfigFileReaderWriter;
import com.github.eostermueller.snail4j.install.AvailableMemoryValidator;
import com.github.eostermueller.snail4j.install.AvailableMemoryValidatorImpl;
import com.github.eostermueller.snail4j.install.DefaultSutInstaller;
import com.github.eostermueller.snail4j.install.DiskSpaceValidator;
import com.github.eostermueller.snail4j.install.DiskSpaceValidatorImpl;
import com.github.eostermueller.snail4j.install.Installer;
import com.github.eostermueller.snail4j.install.Snail4jInstaller;
import com.github.eostermueller.snail4j.launcher.BootstrapConfig;
Expand All @@ -29,6 +35,9 @@
import com.github.eostermueller.snail4j.processmodel.LoadGenerator;
import com.github.eostermueller.snail4j.processmodel.ProcessModelBuilder;
import com.github.eostermueller.snail4j.processmodel.SystemUnderTest;
import com.github.eostermueller.snail4j.systemproperty.AvailableDiskSpaceValidation;
import com.github.eostermueller.snail4j.systemproperty.SystemPropertyManager;
import com.github.eostermueller.snail4j.systemproperty.SystemPropertyManagerImpl;
import com.google.common.flogger.FluentLogger;

public class DefaultFactory implements Factory {
Expand All @@ -55,6 +64,22 @@ private DefaultFactory() {

static EventHistory eventHistory = new EventHistory();
static Factory FACTORY_INSTANCE = null;
static SystemPropertyManager SYSTEM_PROPERTY_MGR_SINGLETON = new SystemPropertyManagerImpl();

@Override
public SystemPropertyManager getSystemPropertyMgr() {
return SYSTEM_PROPERTY_MGR_SINGLETON;
}
/**
* Must only be called during JUnit tests!!!!
* @param testRepo
*/
@Override
public void setSystemPropertyTestValueRepo(SystemPropertyManager testRepo) {
SystemPropertyManagerImpl impl = (SystemPropertyManagerImpl) this.getSystemPropertyMgr();
impl.setSystemPropertyTestValueRepository(testRepo);
}


/**
* @stolenFrom: https://stackoverflow.com/questions/7855700/why-is-volatile-used-in-double-checked-locking
Expand All @@ -70,6 +95,10 @@ public void setConfiguration(Configuration cfg) {
this.configuration = cfg;
}
}
@Override
public GenericConfigFileReaderWriter getGenericConfigReaderWriter() {
return new DefaultGenericConfigFileReaderWriter();
}
@Override
public Configuration getConfiguration() throws Snail4jException {
return getConfiguration( new BootstrapConfig() );
Expand Down Expand Up @@ -268,10 +297,23 @@ public LoadGenerator createLoadGenerator() throws Snail4jException {
public Installer createSutInstaller() throws Snail4jException {
return new DefaultSutInstaller();
}

@Override
public NonPersistentParameters getNonPersistentParameters() {
return new DefaultNonPersistentParameters();
/**
* calling this is Required at the end of unit tests that invoke Factory#setSystemPropertyTestValueRepo();
* ...calling this does no harm (nor provides any particular benefit) in production code.
* Calling this wipes out all JUnit system properties defined by Factory#setSystemPropertyTestValueRepo() ).
*
*/
public void resetUnitTestSystemProperties() {
setSystemPropertyTestValueRepo(null);
}


}
@Override
public AvailableMemoryValidator getAvailableMemoryValidator() throws Snail4jException {
return new AvailableMemoryValidatorImpl();
}
@Override
public DiskSpaceValidator getDiskSpaceValidator() throws Snail4jException {
return new DiskSpaceValidatorImpl();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.github.eostermueller.snail4j.config;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

import com.github.eostermueller.snail4j.DefaultFactory;
import com.github.eostermueller.snail4j.Snail4jException;

/**
* Very possible that multiple threads might write to config files concurrently,
* in edge cases that will only happen occasionally.
* I do not at all expect to have sustained concurrent load reading/writing config files.
* .....that's why I used FileChannel below instead of other techniques.
*
*
* @author eoste
*
*/
public class DefaultGenericConfigFileReaderWriter implements GenericConfigFileReaderWriter {

/**
// File write will fail if some other process/thread is writing to the same file.
* @throws Snail4jException
* @stolenFrom: https://www.geeksforgeeks.org/filechannel-class-trylock-method-in-java-with-examples/
*/
@Override
public void write(String input, Path targetFile) throws Snail4jException {
FileChannel fc = null;
try {
ByteBuffer buf = ByteBuffer.wrap(input.getBytes());
fc = FileChannel.open(
targetFile, StandardOpenOption.WRITE,
StandardOpenOption.CREATE);

fc.tryLock(0L, Long.MAX_VALUE, false);

fc.write(buf);

} catch (Exception e) {
String message = DefaultFactory.getFactory().getMessages().exceptionWritingConfigFile(targetFile,e);
throw new Snail4jException(e,message);
} finally {
try {
if (fc!=null)
fc.close();
} catch (IOException e) {}

}

}

/**
* Stolen from https://www.tabnine.com/code/java/methods/java.nio.CharBuffer/toString?snippet=5ce6e25c2fd3800004eb7fff
*/
@Override
public String read(Path targetFile) throws Snail4jException {

Charset charset = Charset.defaultCharset();
try (FileChannel fc = FileChannel.open(targetFile)) {
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
return charset.decode(bb).toString();
} catch (IOException e) {
String message = DefaultFactory.getFactory().getMessages().exceptionReadingConfigFile(targetFile,e);
throw new Snail4jException(e,message);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.github.eostermueller.snail4j.config;

import java.nio.file.Path;

import com.github.eostermueller.snail4j.Snail4jException;

/**
* Not meant for high count of writes to the same file.
* Not meant for writes of large number of bytes
*
* @author eoste
*
*/
public interface GenericConfigFileReaderWriter {
void write(String data, Path targetFile) throws Snail4jException;
String read(Path targetFile) throws Snail4jException;
}


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package com.github.eostermueller.snail4j.config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.github.eostermueller.snail4j.install;

import com.github.eostermueller.snail4j.Snail4jException;

public interface AvailableMemoryValidator {

void setMinMemoryAvailableRequirementInBytes(long m);
long getMinMemoryAvailableRequirementInBytes();
void setActualMemoryAvailableInBytes(long m);
long getActualMemoryAvailabilInBytes();


boolean isAvailableMemoryValidationActive();
void setAvailableMemoryValidationActive(boolean a);

void validate() throws Snail4jException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.github.eostermueller.snail4j.install;

import com.github.eostermueller.snail4j.DefaultFactory;
import com.github.eostermueller.snail4j.Snail4jException;
import com.github.eostermueller.snail4j.systemproperty.AvailableMemoryValidation;

public class AvailableMemoryValidatorImpl implements AvailableMemoryValidator {

public AvailableMemoryValidatorImpl() throws Snail4jException {

this.setAvailableMemoryValidationActive( DefaultFactory.getFactory().getSystemPropertyMgr().getBoolean(new AvailableMemoryValidation()));

this.setActualMemoryAvailableInBytes( Runtime.getRuntime().freeMemory() );

}
private long minMemoryAvailableRequirementInBytes = 0;
private long actualMemoryAvailableInBytes = 0;


private boolean availableMemoryValidationActive;
private boolean availableDiskSpaceValidationActive;

@Override
public void setMinMemoryAvailableRequirementInBytes(long m) {
this.minMemoryAvailableRequirementInBytes = m;
}

@Override
public long getMinMemoryAvailableRequirementInBytes() {
return this.minMemoryAvailableRequirementInBytes;
}

@Override
public void setActualMemoryAvailableInBytes(long m) {
this.actualMemoryAvailableInBytes = m;
}

@Override
public long getActualMemoryAvailabilInBytes() {
return this.actualMemoryAvailableInBytes;
}





@Override
public void validate() throws Snail4jException {

if (this.isAvailableMemoryValidationActive()) {
if (
this.getActualMemoryAvailabilInBytes() < this.getMinMemoryAvailableRequirementInBytes()
) {
String m = DefaultFactory.getFactory().getMessages().insufficientMemory(this.getActualMemoryAvailabilInBytes(),this.getMinMemoryAvailableRequirementInBytes());
throw new Snail4jException(m);
}
}

}

@Override
public boolean isAvailableMemoryValidationActive() {
return this.availableMemoryValidationActive;
}

@Override
public void setAvailableMemoryValidationActive(boolean a) {
this.availableMemoryValidationActive = a;
}


}
Loading

0 comments on commit d09e9c8

Please sign in to comment.