Skip to content

Commit

Permalink
Initial commit of publisher points table
Browse files Browse the repository at this point in the history
Many things outstanding, this is just a proof of concept for H2
  • Loading branch information
terrypacker committed Aug 30, 2019
1 parent 635129f commit 05d3376
Show file tree
Hide file tree
Showing 14 changed files with 678 additions and 8 deletions.
5 changes: 5 additions & 0 deletions Core/classes/i18n.properties
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ common.logic.not=Not

common.invalidRql=Invalid RQL

database.missingModelMapping=No model mapping for {0} to {1}

share.sharing=Sharing
share.userName=Username
share.accessType=Access type
Expand Down Expand Up @@ -1722,6 +1724,7 @@ event.audit.eventHandler=Event handler
event.audit.jsonData=Json data
event.audit.eventDetector=Event detector
event.audit.publisher=Publisher
event.audit.publishedPoint=Published point
event.audit.mailingList=Mailing list

event.audit.changedProperty=<br/>&nbsp;&nbsp;&nbsp;&nbsp;{0}: "{1}" to "{2}"
Expand Down Expand Up @@ -2095,6 +2098,7 @@ emport.error.pointType.invalid=Point type has an invalid ''{0}'' value of ''{1}'
emport.error.permission.missing=Missing ''{0}'' in point permission
emport.error.missingSource=Data source with XID ''{0}'' not found
emport.error.missingPoint=Data point with XID ''{0}'' not found
emport.error.missingPublisher=Publisher with XID ''{0}'' not found
emport.error.attractor.missingPoint=Data point with ''{0}'' XID ''{1}'' not found
emport.error.ped.missing=Point event detector must have a ''{0}''. Valid values are {1}
emport.error.ped.missingAttr=Point event detector must have a ''{0}''.
Expand Down Expand Up @@ -2150,6 +2154,7 @@ internal.monitor.pollingDataSource.SUCCESS={0} previous sequential successful po
internal.monitor.pollingDataSource.DURATION={0} last poll duration
internal.monitor.pollingDataSource.PERCENTAGE={0} poll success percentage
internal.monitor.JSON_DATA_COUNT=JSON data entries
internal.monitor.PUBLISHED_POINT_COUNT=Published points

java.monitor.JAVA_FREE_MEMORY=JVM free memory (MB)
java.monitor.JAVA_USED_MEMORY=JVM used memory (MB)
Expand Down
18 changes: 18 additions & 0 deletions Core/db/createTables-H2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,24 @@ CREATE TABLE publishers (
);
ALTER TABLE publishers ADD CONSTRAINT publishersUn1 UNIQUE (xid);

CREATE TABLE publishedPoints (
id int NOT NULL auto_increment,
xid varchar(100) NOT NULL,
name varchar(255),
enabled char(1),
publisherId int NOT NULL,
dataPointId int NOT NULL,
data longtext NOT NULL,
PRIMARY KEY (id)
);
ALTER TABLE publishedPoints ADD CONSTRAINT publisherPointsUn1 UNIQUE (xid);
ALTER TABLE publishedPoints ADD CONSTRAINT publisherPointsFk1 FOREIGN KEY (publisherId) REFERENCES publishers(id);
ALTER TABLE publishedPoints ADD CONSTRAINT publisherPointsFk2 FOREIGN KEY (dataPointId) REFERENCES dataPoints(id);

CREATE INDEX publishedPointNameIndex on publishedPoints (name ASC);
CREATE INDEX publishedPointEnabledIndex on publishedPoints (enabled ASC);
CREATE INDEX publishedPointXidNameIndex on publishedPoints (xid ASC, name ASC);

--
--
-- JsonData
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (C) 2019 Infinite Automation Software. All rights reserved.
*/
package com.infiniteautomation.mango.spring.db;

import org.springframework.stereotype.Component;

import com.serotonin.m2m2.vo.publish.mock.MockPublishedPointDatabaseV1Model;
import com.serotonin.m2m2.vo.publish.mock.MockPublishedPointVO;

/**
* @author Terry Packer
*
*/
@Component
public class MockPublishedPointDatabaseModelV1Mapping implements DatabaseModelJacksonMapping<MockPublishedPointVO, MockPublishedPointDatabaseV1Model> {

@Override
public Class<? extends MockPublishedPointVO> fromClass() {
return MockPublishedPointVO.class;
}

@Override
public Class<? extends MockPublishedPointDatabaseV1Model> toClass() {
return MockPublishedPointDatabaseV1Model.class;
}

@Override
public MockPublishedPointDatabaseV1Model map(Object from, DatabaseModelMapper mapper) {
return new MockPublishedPointDatabaseV1Model((MockPublishedPointVO)from);
}

@Override
public String getVersion() {
return MockPublishedPointDatabaseV1Model.class.getName();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright (C) 2019 Infinite Automation Software. All rights reserved.
*/
package com.serotonin.m2m2.vo.publish;

import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.serotonin.m2m2.DataTypes;
import com.serotonin.m2m2.MangoTestBase;
import com.serotonin.m2m2.db.dao.DataPointDao;
import com.serotonin.m2m2.db.dao.DataSourceDao;
import com.serotonin.m2m2.db.dao.PublishedPointDao;
import com.serotonin.m2m2.db.dao.PublisherDao;
import com.serotonin.m2m2.module.ModuleElementDefinition;
import com.serotonin.m2m2.vo.DataPointVO;
import com.serotonin.m2m2.vo.dataPoint.MockPointLocatorVO;
import com.serotonin.m2m2.vo.dataSource.mock.MockDataSourceVO;
import com.serotonin.m2m2.vo.publish.mock.MockPublishedPointVO;
import com.serotonin.m2m2.vo.publish.mock.MockPublisherDefinition;
import com.serotonin.m2m2.vo.publish.mock.MockPublisherVO;

/**
* @author Terry Packer
*
*/
public class PublishedPointTest extends MangoTestBase {

@BeforeClass
public static void addDefinitions() {
List<ModuleElementDefinition> definitions = new ArrayList<>();
definitions.add(new MockPublisherDefinition());
addModule("mockPublisher", definitions);
}

@Test
public void testPublisherAuditTrail() {
MockPublisherVO pub = new MockPublisherVO();
pub.setDefinition(new MockPublisherDefinition());
pub.setXid("PUB_TEST1");
pub.setEnabled(false);
PublisherDao.getInstance().savePublisher(pub);

MockDataSourceVO ds = new MockDataSourceVO();
ds.setXid("DS_TEST1");
ds.setName("TEST");
DataSourceDao.getInstance().save(ds);

//Save a point
DataPointVO dp = new DataPointVO();
dp.setXid("DP_1");
dp.setName("Data point name");
dp.setPointLocator(new MockPointLocatorVO(DataTypes.NUMERIC, true));
dp.setDataSourceId(ds.getId());
DataPointDao.getInstance().save(dp);

//Save publisher point
MockPublishedPointVO pp = new MockPublishedPointVO();
pp.setXid(PublishedPointDao.getInstance().generateUniqueXid());
pp.setName("Test published point");
pp.setPublisherId(pub.getId());
pp.setDataPointId(dp.getId());
pp.setMockSetting("mock setting");
pp.ensureValid();
PublishedPointDao.getInstance().save(pp);

//Verify the point was created correctly
MockPublishedPointVO mpp = (MockPublishedPointVO)PublishedPointDao.getInstance().get(pp.getId());
Assert.assertEquals(pp.getId(), mpp.getId());
Assert.assertEquals(pp.getXid(), mpp.getXid());
Assert.assertEquals(pp.getName(), mpp.getName());
Assert.assertEquals(pp.isEnabled(), mpp.isEnabled());
Assert.assertEquals(pp.getPublisherId(), mpp.getPublisherId());
Assert.assertEquals(pp.getDataPointId(), mpp.getDataPointId());
Assert.assertEquals(pp.getMockSetting(), mpp.getMockSetting());

//TODO Verify Audit Events
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (C) 2019 Infinite Automation Software. All rights reserved.
*/
package com.serotonin.m2m2.vo.publish.mock;

import org.springframework.stereotype.Component;

import com.serotonin.m2m2.db.dao.PublishedPointDao.PublishedPointSettingsDatabaseModel;
import com.serotonin.m2m2.vo.publish.PublishedPointVO;

/**
* @author Terry Packer
*
*/
@Component
public class MockPublishedPointDatabaseV1Model extends PublishedPointSettingsDatabaseModel {

private String setting;

public MockPublishedPointDatabaseV1Model() {

}

public MockPublishedPointDatabaseV1Model(MockPublishedPointVO vo) {
this.setting = vo.getMockSetting();
}

public String getSetting() {
return setting;
}

public void setSetting(String setting) {
this.setting = setting;
}

@Override
public PublishedPointVO toVO() {
MockPublishedPointVO vo = new MockPublishedPointVO();
vo.setMockSetting(setting);
return vo;
}

@Override
public String getVersion() {
return this.getClass().getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@
*
* @author Terry Packer
*/
public class MockPublishedPointVO extends PublishedPointVO{
public class MockPublishedPointVO extends PublishedPointVO {

private String mockSetting;

public String getMockSetting() {
return mockSetting;
}

public void setMockSetting(String mockSetting) {
this.mockSetting = mockSetting;
}

/* (non-Javadoc)
* @see com.serotonin.m2m2.vo.publish.PublishedPointVO#asModel()
*/
@Override
public AbstractPublishedPointModel<?> asModel() {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (C) 2019 Infinite Automation Software. All rights reserved.
*/
package com.infiniteautomation.mango.spring.db;

import com.fasterxml.jackson.annotation.JsonTypeInfo;

/**
* @author Terry Packer
*
*/
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.EXISTING_PROPERTY, property=AbstractDatabaseModel.VERSION_FIELD)
public abstract class AbstractDatabaseModel {

public static final String VERSION_FIELD = "version";

/**
* Ensure the model has a version
* @return
*/
public abstract String getVersion();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (C) 2019 Infinite Automation Software. All rights reserved.
*/
package com.infiniteautomation.mango.spring.db;

/**
* Used to ensure Jackson is able to de-serialize the model (type T) in this mapping
*
* @author Terry Packer
*
*/
public interface DatabaseModelJacksonMapping <F, T> extends DatabaseModelMapping<F, T> {

/**
* Return the type name that maps the T class (Model) to a Type in Jackson
* in the DAO layer we call this the version
*/
public String getVersion();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright (C) 2019 Infinite Automation Software. All rights reserved.
*/
package com.infiniteautomation.mango.spring.db;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.infiniteautomation.mango.spring.MangoRuntimeContextConfiguration;
import com.infiniteautomation.mango.util.exception.TranslatableRuntimeException;
import com.serotonin.m2m2.i18n.TranslatableMessage;

/**
* Gets a list of DatabaseModelMapping beans from the Spring context and uses them to convert an object to its model.
* The DatabaseModelMapping beans can be annotated with @Order to specify their priority.
*
* @author Terry Packer
*
*/
@Component
public class DatabaseModelMapper {
private final List<DatabaseModelMapping<?,?>> mappings;

@Autowired
public DatabaseModelMapper(Optional<List<DatabaseModelMapping<?,?>>> mappings,
@Qualifier(MangoRuntimeContextConfiguration.DAO_OBJECT_MAPPER_NAME)ObjectMapper objectMapper) {
this.mappings = mappings.orElseGet(Collections::emptyList);

//Load in the mappings for Jackson
for(DatabaseModelMapping<?,?> mapping : this.mappings) {
if(mapping instanceof DatabaseModelJacksonMapping)
objectMapper.registerSubtypes(new NamedType(mapping.toClass(), ((DatabaseModelJacksonMapping<?,?>)mapping).getVersion()));
}
}

public <T> T map(Object from, Class<T> model) {
Objects.requireNonNull(from);
Objects.requireNonNull(model);

for (DatabaseModelMapping<?,?> mapping : mappings) {
if (mapping.supports(from, model)) {
@SuppressWarnings("unchecked")
T result = (T) mapping.map(from, this);
if (result != null) {
return result;
}
}
}

throw new TranslatableRuntimeException(new TranslatableMessage("database.missingModelMapping", from.getClass(), model));
}

}
Loading

0 comments on commit 05d3376

Please sign in to comment.