Skip to content

Commit

Permalink
Merge pull request #598 from marklogic-community/feature/bug-558
Browse files Browse the repository at this point in the history
Feature/bug 558
  • Loading branch information
dmcassel authored Dec 1, 2017
2 parents 111806e + de2ecf6 commit 3e7c4e8
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import com.marklogic.hub.flow.FlowType;
import com.marklogic.hub.scaffold.Scaffolding;
import com.marklogic.quickstart.auth.ConnectionAuthenticationToken;
import com.marklogic.quickstart.listeners.DeployUserModulesListener;
import com.marklogic.quickstart.listeners.ValidateListener;
import com.marklogic.quickstart.model.EnvironmentConfig;
import com.marklogic.quickstart.model.FlowModel;
import com.marklogic.quickstart.model.PluginModel;
Expand Down Expand Up @@ -68,14 +70,17 @@ public class EntityManagerService {
private static final String UI_LAYOUT_FILE = "entities.layout.json";
private static final String PLUGINS_DIR = "plugins";
private static final String ENTITIES_DIR = "entities";
private static final String ENTITY_FILE_EXTENSION = ".entity.json";
public static final String ENTITY_FILE_EXTENSION = ".entity.json";

@Autowired
private FlowManagerService flowManagerService;

@Autowired
private FileSystemWatcherService watcherService;

@Autowired
private DataHubService dataHubService;

private EnvironmentConfig envConfig() {
ConnectionAuthenticationToken authenticationToken = (ConnectionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
return authenticationToken.getEnvironmentConfig();
Expand Down Expand Up @@ -156,18 +161,50 @@ public EntityModel createEntity(String projectDir, EntityModel newEntity) throws
public EntityModel saveEntity(EntityModel entity) throws IOException {
JsonNode node = entity.toJson();
ObjectMapper objectMapper = new ObjectMapper();
String filename = entity.getFilename();
if (filename == null) {
String title = entity.getInfo().getTitle();
String fullpath = entity.getFilename();
String title = entity.getInfo().getTitle();

if (fullpath == null) {
Path dir = Paths.get(envConfig().getProjectDir(), PLUGINS_DIR, ENTITIES_DIR, title);
if (!dir.toFile().exists()) {
dir.toFile().mkdirs();
}
filename = Paths.get(dir.toString(), title + ENTITY_FILE_EXTENSION).toString();
fullpath = Paths.get(dir.toString(), title + ENTITY_FILE_EXTENSION).toString();
}
else {
String filename = new File(fullpath).getName();
String entityFromFilename = filename.substring(0, filename.indexOf(ENTITY_FILE_EXTENSION));
if (!entityFromFilename.equals(entity.getName())) {
// The entity name was changed since the files were created. Update
// the path.

// Update the name of the entity definition file
File origFile = new File(fullpath);
File newFile = new File(origFile.getParent() + File.separator + title + ENTITY_FILE_EXTENSION);
if (!origFile.renameTo(newFile)) {
throw new IOException("Unable to rename " + origFile.getAbsolutePath() + " to " +
newFile.getAbsolutePath());
};

// Update the directory name
File origDirectory = new File(origFile.getParent());
File newDirectory = new File(origDirectory.getParent() + File.separator + title);
if (!origDirectory.renameTo(newDirectory)) {
throw new IOException("Unable to rename " + origDirectory.getAbsolutePath() + " to " +
newDirectory.getAbsolutePath());
}

fullpath = newDirectory.getAbsolutePath() + File.separator + title + ENTITY_FILE_EXTENSION;
entity.setFilename(fullpath);

// Redeploy the flows
dataHubService.reinstallUserModules(envConfig().getMlSettings(), null, null);
}
}


String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
FileUtils.writeStringToFile(new File(filename), json);
FileUtils.writeStringToFile(new File(fullpath), json);

return entity;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package com.marklogic.quickstart.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.marklogic.hub.HubConfig;
import com.marklogic.hub.HubTestBase;
import com.marklogic.hub.flow.CodeFormat;
import com.marklogic.hub.flow.DataFormat;
import com.marklogic.hub.flow.FlowType;
import com.marklogic.hub.scaffold.Scaffolding;
import com.marklogic.hub.util.FileUtil;
import com.marklogic.quickstart.auth.ConnectionAuthenticationToken;
import com.marklogic.quickstart.model.EnvironmentConfig;
import com.marklogic.quickstart.model.FlowModel;
import com.marklogic.quickstart.model.entity_services.EntityModel;
import org.apache.commons.io.FileUtils;
import org.junit.*;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest()
public class EntityManagerServiceTest extends HubTestBase {

private static String ENTITY = "test-entity";
private static String ENTITY2 = "test-entity2";
private static Path projectDir = Paths.get(".", PROJECT_PATH);

@Autowired
EntityManagerService entityMgrService;

@BeforeClass
public static void setupSuite() throws IOException {
FileUtils.deleteDirectory(projectDir.toFile());

EnvironmentConfig envConfig = new EnvironmentConfig(projectDir.toString(), "local", "admin", "admin");
envConfig.setMlSettings(HubConfig.hubFromEnvironment(projectDir.toString(), null));
envConfig.checkIfInstalled();
setEnvConfig(envConfig);

installHub();
}

private static void setEnvConfig(EnvironmentConfig envConfig) {
ConnectionAuthenticationToken authenticationToken = new ConnectionAuthenticationToken("admin", "admin", "localhost", 1, "local");
authenticationToken.setEnvironmentConfig(envConfig);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}

@Before
public void setUp() throws IOException {
FileUtils.deleteDirectory(projectDir.toFile());

Scaffolding scaffolding = new Scaffolding(projectDir.toString(), stagingClient);
scaffolding.createEntity(ENTITY);
scaffolding.createFlow(ENTITY, "sjs-json-input-flow", FlowType.INPUT,
CodeFormat.JAVASCRIPT, DataFormat.JSON);

scaffolding.createFlow(ENTITY, "sjs-xml-input-flow", FlowType.INPUT,
CodeFormat.JAVASCRIPT, DataFormat.XML);

scaffolding.createFlow(ENTITY, "xqy-json-input-flow", FlowType.INPUT,
CodeFormat.XQUERY, DataFormat.JSON);

scaffolding.createFlow(ENTITY, "xqy-xml-input-flow", FlowType.INPUT,
CodeFormat.XQUERY, DataFormat.XML);

Path entityDir = projectDir.resolve("plugins/entities/" + ENTITY);
Path inputDir = entityDir.resolve("input");

String entityFilename = ENTITY + EntityManagerService.ENTITY_FILE_EXTENSION;
FileUtil.copy(getResourceStream(entityFilename), entityDir.resolve(entityFilename).toFile());

FileUtil.copy(getResourceStream("flow-manager/sjs-flow/headers.sjs"), inputDir.resolve("sjs-json-input-flow/headers.sjs").toFile());
FileUtil.copy(getResourceStream("flow-manager/sjs-flow/content-input.sjs"), inputDir.resolve("sjs-json-input-flow/content.sjs").toFile());
FileUtil.copy(getResourceStream("flow-manager/sjs-flow/triples.sjs"), inputDir.resolve("sjs-json-input-flow/triples.sjs").toFile());

FileUtil.copy(getResourceStream("flow-manager/sjs-flow/headers.sjs"), inputDir.resolve("sjs-xml-input-flow/headers.sjs").toFile());
FileUtil.copy(getResourceStream("flow-manager/sjs-flow/content-input.sjs"), inputDir.resolve("sjs-xml-input-flow/content.sjs").toFile());
FileUtil.copy(getResourceStream("flow-manager/sjs-flow/triples.sjs"), inputDir.resolve("sjs-xml-input-flow/triples.sjs").toFile());

FileUtil.copy(getResourceStream("flow-manager/xqy-flow/headers-json.xqy"), inputDir.resolve("xqy-json-input-flow/headers.xqy").toFile());
FileUtil.copy(getResourceStream("flow-manager/xqy-flow/content-input.xqy"), inputDir.resolve("xqy-json-input-flow/content.xqy").toFile());
FileUtil.copy(getResourceStream("flow-manager/xqy-flow/triples.xqy"), inputDir.resolve("xqy-json-input-flow/triples.xqy").toFile());

FileUtil.copy(getResourceStream("flow-manager/xqy-flow/headers-xml.xqy"), inputDir.resolve("xqy-xml-input-flow/headers.xqy").toFile());
FileUtil.copy(getResourceStream("flow-manager/xqy-flow/content-input.xqy"), inputDir.resolve("xqy-xml-input-flow/content.xqy").toFile());
FileUtil.copy(getResourceStream("flow-manager/xqy-flow/triples.xqy"), inputDir.resolve("xqy-xml-input-flow/triples.xqy").toFile());

getDataHub().installUserModules(true);
}

@AfterClass
public static void tearDown() throws IOException {
FileUtils.deleteDirectory(projectDir.toFile());
uninstallHub();
}

@Test
public void getEntities() throws IOException {
List<EntityModel> entities = entityMgrService.getEntities();

Assert.assertEquals(1, entities.size());
Assert.assertEquals(ENTITY, entities.get(0).getName());
}

@Test
public void saveEntity() throws IOException {
Path entityDir = projectDir.resolve("plugins/entities/" + ENTITY);
String entityFilename = ENTITY2 + EntityManagerService.ENTITY_FILE_EXTENSION;

JsonNode node = getJsonFromResource(entityFilename);

EntityModel entity = EntityModel.fromJson(entityFilename, node);
entity.setFilename(entityDir.resolve(entityFilename).toString());

entityMgrService.saveEntity(entity);

List<EntityModel> entities = entityMgrService.getEntities();

Assert.assertEquals(2, entities.size());
String[] expected = {ENTITY, ENTITY2};
String[] actual = { entities.get(0).getName(), entities.get(1).getName() };
Assert.assertArrayEquals(expected, actual);
}

@Test
public void getEntity() throws IOException {
EntityModel entity = entityMgrService.getEntity(ENTITY);

Assert.assertEquals(ENTITY, entity.getName());
Assert.assertEquals(4, entity.getInputFlows().size());
Assert.assertEquals(0, entity.getHarmonizeFlows().size());
}

@Test public void getNoSuchEntity() throws IOException {
EntityModel entity = entityMgrService.getEntity("no-such-entity");

Assert.assertNull(entity);
}

@Test
public void getFlow() throws IOException {
final String FLOW_NAME = "sjs-json-input-flow";
FlowModel flow = entityMgrService.getFlow(ENTITY, FlowType.INPUT, FLOW_NAME);
Assert.assertEquals(ENTITY, flow.entityName);
Assert.assertEquals(FLOW_NAME, flow.flowName);
Assert.assertEquals(FlowType.INPUT, flow.flowType);
}

@Test
public void getNoSuchFlow() throws IOException {
final String FLOW_NAME = "no-such-flow";
FlowModel flow = entityMgrService.getFlow(ENTITY, FlowType.INPUT, FLOW_NAME);
Assert.assertNull(flow);
}

/**
* Try getting a flow using the name of a valid flow, but requesting using the wrong type.
* @throws IOException
*/
@Test
public void getFlowByWrongType() throws IOException {
final String FLOW_NAME = "sjs-json-input-flow";
FlowModel flow = entityMgrService.getFlow(ENTITY, FlowType.HARMONIZE, FLOW_NAME);
Assert.assertNull(flow);
}

/**
* Addresses https://github.com/marklogic-community/marklogic-data-hub/issues/558.
*/
@Test
public void changeEntityName() throws IOException {
final String RENAMED_ENTITY = "renamed-entity";

// Get the original entity
EntityModel entity = entityMgrService.getEntity(ENTITY);

// Convert to String and change the title (the UI just changes the title property)
String strEntity = entity.toJson().toString();
strEntity = strEntity.replaceFirst("\"title\"\\s*:\\s*\"test-entity\"", "\"title\" : \"" + RENAMED_ENTITY + "\"");
strEntity = strEntity.replaceFirst("\"test-entity\"\\s*:", "\"" + RENAMED_ENTITY + "\" :");

// Convert back to JsonNode
ObjectMapper mapper = new ObjectMapper();
JsonNode renamed = mapper.readTree(strEntity);
EntityModel renamedEntity = EntityModel.fromJson(entity.getFilename(), renamed);

// Save the renamedEntity
entityMgrService.saveEntity(renamedEntity);

List<EntityModel> entities = entityMgrService.getEntities();
Assert.assertEquals(1, entities.size());

// Load the entity, then check the flows to make sure they know the right entity name
final String FLOW_NAME = "sjs-json-input-flow";
List<FlowModel> inputFlows = entities.get(0).getInputFlows();

Assert.assertEquals(RENAMED_ENTITY, inputFlows.get(0).entityName);
Assert.assertEquals(FLOW_NAME, inputFlows.get(0).flowName);
Assert.assertEquals(FlowType.INPUT, inputFlows.get(0).flowType);

}
}
15 changes: 15 additions & 0 deletions quick-start/src/test/resources/test-entity.entity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"info" : {
"title" : "test-entity",
"version" : "0.0.1"
},
"definitions" : {
"test-entity" : {
"required" : [ ],
"rangeIndex" : [ ],
"wordLexicon" : [ ],
"properties" : {
}
}
}
}
15 changes: 15 additions & 0 deletions quick-start/src/test/resources/test-entity2.entity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"info" : {
"title" : "test-entity2",
"version" : "0.0.1"
},
"definitions" : {
"test-entity2" : {
"required" : [ ],
"rangeIndex" : [ ],
"wordLexicon" : [ ],
"properties" : {
}
}
}
}

0 comments on commit 3e7c4e8

Please sign in to comment.