Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,38 @@
import com.acme.commands.StatusCommand;
import com.acme.executors.ICommandExecutor;
import com.acme.executors.SimpleCommandExecutor;
import org.springframework.beans.factory.annotation.Autowired;

/**
* Command for determining the basic disk status
*/
public class BasicDiskStatusCmd implements StatusCommand {
public class DiskStatusCmd implements StatusCommand {

private ICommandExecutor executor;

private final long Id;
private final String template;
private final String name;
private final GenerateDiskStatusCmd cmd;

private DiskStatus status;

public BasicDiskStatusCmd(long Id, String template, String name) {
public DiskStatusCmd(long Id, String template, String name, GenerateDiskStatusCmd cmd) {
this.Id = Id;
this.template = template;
this.name = name;
this.cmd = cmd;

executor = new SimpleCommandExecutor();
}

public DiskStatusCmd(long Id, String template, String name) {
this(Id, template, name, new GenerateDiskStatusCmd());
}

@Override
public void execute() {
status = new DiskStatus(Id, String.format(template, name));
GenerateDiskStatusCmd cmd = new GenerateDiskStatusCmd();
executor.executeCommand(cmd);
status = new DiskStatus(Id, String.format(template, name));
status.setStatusDesc(cmd.getResult());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.acme.commands.Disk;

import com.acme.beans.DiskStatus;

public class FastResponseDiskStatusCmd extends DiskStatusCmd {

private final long Id;
private final String template;
private final String name;

private DiskStatusCmd cmd;

public FastResponseDiskStatusCmd(long Id, String template, String name, DiskStatusCmd cmd) {
super(Id, template, name);

this.Id = Id;
this.template = template;
this.name = name;
this.cmd = cmd;
}

public FastResponseDiskStatusCmd(long Id, String template, String name) {
this(Id, template, name, new DiskStatusCmd(Id, template, name));
}

@Override
public void execute() {
Thread executionThread = new Thread( () -> cmd.execute() );
executionThread.start();
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public DiskStatus getResult() {
DiskStatus result = cmd.getResult();
if (result == null || result.getStatusDesc() == null){
result = new DiskStatus(Id, String.format(template, name));
result.setStatusDesc("Unknown");
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.acme.commands.Disk;

/**
* Singleton proxy for generating the disk status, so that only one instance of the command will be executed at once
*/
public class ResourceEfficientDiskStatusGenerationCmd extends GenerateDiskStatusCmd {

private String statusDesc = "unknown";

private boolean isRunning;
private static ResourceEfficientDiskStatusGenerationCmd cmd = new ResourceEfficientDiskStatusGenerationCmd();

private ResourceEfficientDiskStatusGenerationCmd() {
}

public static ResourceEfficientDiskStatusGenerationCmd getInstance(){
return cmd;
}

@Override
public void execute() {

boolean willExecute;
synchronized (this){
if (isRunning){
willExecute = false;
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
isRunning = true;
willExecute = true;
}
}

if (willExecute){
statusDesc = super.createStatusDesc();
synchronized (this){
isRunning = false;
this.notifyAll();
}
}

}

@Override
public String getResult() {
return statusDesc;
}

}
49 changes: 49 additions & 0 deletions src/main/java/com/acme/commands/Disk/SecureDiskStatusCmd.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.acme.commands.Disk;

import com.acme.beans.DiskStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.MethodHandles;

/**
* Proxy decorator for ensuring that only registered users can execute the disk status command
*/
public class SecureDiskStatusCmd extends DiskStatusCmd {
private final long Id;
private final String template;
private final String name;

private DiskStatusCmd cmd;

protected static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

public SecureDiskStatusCmd(long Id, String template, String name, DiskStatusCmd cmd) {
super(Id, template, name);

this.Id = Id;
this.template = template;
this.name = name;
this.cmd = cmd;
}

public SecureDiskStatusCmd(long Id, String template, String name) {
this(Id, template, name, new DiskStatusCmd(Id, template, name));
}

@Override
public void execute() {
if (name == null || name.equals("Anonymous")) {
return;
}

LOGGER.info("User '{}' was allowed to access disk status information", name);

cmd.execute();
}

@Override
public DiskStatus getResult() {
return cmd.getResult();
}
}
9 changes: 7 additions & 2 deletions src/main/java/com/acme/statusmgr/StatusController.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.acme.statusmgr;

import com.acme.DecoratorFactory;
import com.acme.commands.Disk.BasicDiskStatusCmd;
import com.acme.commands.Disk.DiskStatusCmd;
import com.acme.commands.Disk.FastResponseDiskStatusCmd;
import com.acme.commands.Disk.ResourceEfficientDiskStatusGenerationCmd;
import com.acme.commands.Disk.SecureDiskStatusCmd;
import com.acme.commands.Server.BasicServerStatusCmd;
import com.acme.commands.Server.DetailedServerStatusCmd;
import com.acme.executors.ICommandExecutor;
Expand Down Expand Up @@ -74,7 +77,9 @@ public ServerStatus getCurrentDetailedServerStatus(@RequestParam(value = "name",

@RequestMapping("/disk/status")
public DiskStatus getCurrentDiskStatus(@RequestParam(value = "name", defaultValue = "Anonymous") String name) {
BasicDiskStatusCmd cmd = new BasicDiskStatusCmd(counter.incrementAndGet(), template, name);
long Id = counter.incrementAndGet();
DiskStatusCmd cmd = new DiskStatusCmd(Id, template, name, ResourceEfficientDiskStatusGenerationCmd.getInstance());
cmd = new SecureDiskStatusCmd(Id, template, name, new FastResponseDiskStatusCmd(Id, template, name, cmd));
executor.executeCommand(cmd);
return cmd.getResult();
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/acme/statusmgr/StatusCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.acme.beans.DiskStatus;
import com.acme.beans.ServerStatus;
import com.acme.beans.complex.ComplexDecoratorFactory;
import com.acme.commands.Disk.BasicDiskStatusCmd;
import com.acme.commands.Disk.DiskStatusCmd;
import com.acme.commands.Server.BasicServerStatusCmd;
import com.acme.commands.Server.DetailedServerStatusCmd;
import com.acme.executors.ICommandExecutor;
Expand Down Expand Up @@ -83,7 +83,7 @@ public void simplifiedDetailedServerStatusCommandShouldCreateSimplifiedStatus()
@Test
public void basicDiskStatusCommandShouldCreateBasicStatus() {

BasicDiskStatusCmd cmd = new BasicDiskStatusCmd(5, "Server Status requested by %s", "Anonymous");
DiskStatusCmd cmd = new DiskStatusCmd(5, "Server Status requested by %s", "Anonymous");

executor.executeCommand(cmd);
DiskStatus result = cmd.getResult();
Expand Down