Skip to content

Commit

Permalink
Normalize definitions in extension tables
Browse files Browse the repository at this point in the history
Here we remove redundant item definition data (name, type, etc)
from m_object_ext_XXX and m_assignment_ext_XXX tables.

Currently repo tests pass, but provisioning ones do not.

Also, there are some unfinished/temporary parts, like storing session
into threadlocal variable; we also need to decide whether to implement
equals/hashcode for ROExt* and RAExt* classes, etc.
  • Loading branch information
mederly committed Feb 9, 2018
1 parent 67bcda4 commit 974f3f5
Show file tree
Hide file tree
Showing 55 changed files with 1,598 additions and 1,901 deletions.
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2010-2018 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.evolveum.midpoint.repo.sql;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.Test;

import java.io.File;

/**
* @author mederly
*/
@ContextConfiguration(locations = {"../../../../../ctx-test.xml"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class DeleteTestSimple extends BaseSQLRepoTest {

private static final Trace LOGGER = TraceManager.getTrace(DeleteTestSimple.class);

@Test
public void delete001() throws Exception {
PrismObject<UserType> user = prismContext.parseObject(new File(FOLDER_BASIC, "user0.xml"));

OperationResult result = new OperationResult("Delete Test");
String oid = repositoryService.addObject(user, null, result);
LOGGER.info("*** deleteObject ***");

// Session session = open();
// CriteriaQuery<RAssignment> aQ = session.getCriteriaBuilder().createQuery(RAssignment.class);
// aQ.select(aQ.from(RAssignment.class));
// List<RAssignment> aList = session.createQuery(aQ).getResultList();
// System.out.println("RAssignment: " + aList);
//
// CriteriaQuery<RAssignmentExtension> aeQ = session.getCriteriaBuilder().createQuery(RAssignmentExtension.class);
// aeQ.select(aeQ.from(RAssignmentExtension.class));
// List<RAssignmentExtension> aeList = session.createQuery(aeQ).getResultList();
// System.out.println("RAssignmentExtension: " + aeList);
//
// CriteriaQuery<RAExtBoolean> aebQ = session.getCriteriaBuilder().createQuery(RAExtBoolean.class);
// aebQ.select(aebQ.from(RAExtBoolean.class));
// List<RAExtBoolean> aebList = session.createQuery(aebQ).getResultList();
// System.out.println("RAExtBoolean: " + aebList);
//
// session.getTransaction().commit();

repositoryService.deleteObject(UserType.class, oid, result);
}
}
Expand Up @@ -83,6 +83,9 @@ public class ModifyTest extends BaseSQLRepoTest {

private static final Trace LOGGER = TraceManager.getTrace(ModifyTest.class);

private static final QName QNAME_LOOT = new QName("http://example.com/p", "loot");
private static final QName QNAME_WEAPON = new QName("http://example.com/p", "weapon");

@BeforeSuite
public void setup() throws SchemaException, SAXException, IOException {
PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX);
Expand Down Expand Up @@ -497,8 +500,6 @@ public void test130ExtensionModify() throws Exception {
final String TEST_NAME = "test130ExtensionModify";
TestUtil.displayTestTitle(TEST_NAME);

final QName QNAME_LOOT = new QName("http://example.com/p", "loot");

File userFile = new File(TEST_DIR, "user-with-extension.xml");
//add first user
PrismObject<UserType> user = prismContext.parseObject(userFile);
Expand Down Expand Up @@ -593,6 +594,83 @@ public void test140ModifyAccountSynchronizationSituation() throws Exception {
System.out.println("shadow: " + shadows.get(0).debugDump());
}

private String accountOid;

@Test
public void test142ModifyAccountAttributeSameValue() throws Exception {
final String TEST_NAME = "test142ModifyAccountAttributeSameValue";
TestUtil.displayTestTitle(TEST_NAME);

OperationResult result = new OperationResult(TEST_NAME);

PrismObject<ShadowType> account = prismContext.parseObject(new File(TEST_DIR, "account-attribute.xml"));
repositoryService.addObject(account, null, result);
accountOid = account.getOid();

PrismPropertyDefinition<String> definition = new PrismPropertyDefinitionImpl<>(SchemaConstants.ICFS_NAME, DOMUtil.XSD_STRING, prismContext);

List<ItemDelta<?, ?>> itemDeltas = DeltaBuilder.deltaFor(ShadowType.class, prismContext)
.item(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstants.ICFS_NAME), definition)
.replace("account123")
.asItemDeltas();

repositoryService.modifyObject(ShadowType.class, accountOid, itemDeltas, getModifyOptions(), result);

PrismObject<ShadowType> afterModify = repositoryService.getObject(ShadowType.class, accountOid, null, result);
AssertJUnit.assertNotNull(afterModify);
ShadowType afterFirstModifyType = afterModify.asObjectable();
System.out.println("shadow: " + afterModify.debugDump());
}

@Test
public void test144ModifyAccountAttributeDifferent() throws Exception {
final String TEST_NAME = "test144ModifyAccountAttributeDifferent";
TestUtil.displayTestTitle(TEST_NAME);

OperationResult result = new OperationResult(TEST_NAME);

assertNotNull("account-attribute was not imported in previous tests", accountOid);

PrismPropertyDefinition<String> definition = new PrismPropertyDefinitionImpl<>(SchemaConstants.ICFS_NAME, DOMUtil.XSD_STRING, prismContext);

List<ItemDelta<?, ?>> itemDeltas = DeltaBuilder.deltaFor(ShadowType.class, prismContext)
.item(new ItemPath(ShadowType.F_ATTRIBUTES, SchemaConstants.ICFS_NAME), definition)
.replace("account-new")
.asItemDeltas();

repositoryService.modifyObject(ShadowType.class, accountOid, itemDeltas, getModifyOptions(), result);

PrismObject<ShadowType> afterModify = repositoryService.getObject(ShadowType.class, accountOid, null, result);
AssertJUnit.assertNotNull(afterModify);
ShadowType afterFirstModifyType = afterModify.asObjectable();
System.out.println("shadow: " + afterModify.debugDump());
}

@Test
public void test148ModifyAssignmentExtension() throws Exception {
final String TEST_NAME = "test148ModifyAssignmentExtension";
TestUtil.displayTestTitle(TEST_NAME);

OperationResult result = new OperationResult(TEST_NAME);

PrismObject<UserType> user = prismContext.parseObject(new File(TEST_DIR, "user-with-assignment-extension.xml"));
repositoryService.addObject(user, null, result);

PrismPropertyDefinition<String> definition = new PrismPropertyDefinitionImpl<>(QNAME_WEAPON, DOMUtil.XSD_STRING, prismContext);

List<ItemDelta<?, ?>> itemDeltas = DeltaBuilder.deltaFor(UserType.class, prismContext)
.item(new ItemPath(UserType.F_ASSIGNMENT, 1, AssignmentType.F_EXTENSION, QNAME_WEAPON), definition)
.replace("knife")
.asItemDeltas();

repositoryService.modifyObject(UserType.class, user.getOid(), itemDeltas, getModifyOptions(), result);

PrismObject<UserType> afterModify = repositoryService.getObject(UserType.class, user.getOid(), null, result);
AssertJUnit.assertNotNull(afterModify);
UserType afterFirstModifyType = afterModify.asObjectable();
System.out.println("user: " + afterModify.debugDump());
}

private String roleOid;

@Test
Expand Down
Expand Up @@ -23,6 +23,10 @@
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.repo.sql.data.common.any.RAExtBoolean;
import com.evolveum.midpoint.repo.sql.data.common.any.RAssignmentExtension;
import com.evolveum.midpoint.repo.sql.data.common.any.RExtItem;
import com.evolveum.midpoint.repo.sql.data.common.container.RAssignment;
import com.evolveum.midpoint.repo.sql.query.QueryException;
import com.evolveum.midpoint.repo.sql.query.RQuery;
import com.evolveum.midpoint.repo.sql.query2.QueryEngine2;
Expand Down Expand Up @@ -59,6 +63,7 @@
import org.testng.annotations.Test;
import org.xml.sax.SAXException;

import javax.persistence.criteria.CriteriaQuery;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import java.io.File;
Expand Down Expand Up @@ -497,7 +502,7 @@ public void test070QueryGenericLong() throws Exception {
" g.oid, g.fullObject, g.stringsCount, g.longsCount, g.datesCount, g.referencesCount, g.polysCount, g.booleansCount\n" +
"from\n" +
" RGenericObject g\n" +
" left join g.longs l with ( l.ownerType = :ownerType and l.name = :name )\n" +
" left join g.longs l with ( l.ownerType = :ownerType and l.item.name = :name )\n" +
"where\n" +
" ( g.name.norm = :norm and l.value = :value )\n";

Expand Down Expand Up @@ -528,8 +533,8 @@ public void test071QueryGenericLongTwice() throws Exception {
" g.oid, g.fullObject, g.stringsCount, g.longsCount, g.datesCount, g.referencesCount, g.polysCount, g.booleansCount\n" +
"from\n" +
" RGenericObject g\n" +
" left join g.longs l with ( l.ownerType = :ownerType and l.name = :name )\n" +
" left join g.longs l2 with ( l2.ownerType = :ownerType2 and l2.name = :name2 )\n" +
" left join g.longs l with ( l.ownerType = :ownerType and l.item.name = :name )\n" +
" left join g.longs l2 with ( l2.ownerType = :ownerType2 and l2.item.name = :name2 )\n" +
"where\n" +
" (\n" +
" g.name.norm = :norm and\n" +
Expand Down Expand Up @@ -558,7 +563,7 @@ public void test072QueryAccountByAttribute() throws Exception {
" s.oid, s.fullObject, s.stringsCount, s.longsCount, s.datesCount, s.referencesCount, s.polysCount, s.booleansCount\n" +
"from\n" +
" RShadow s\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.name = :name )\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.item.name = :name )\n" +
"where\n" +
" s2.value = :value\n";
assertEqualsIgnoreWhitespace(expected, real);
Expand All @@ -578,8 +583,8 @@ public void test074QueryAccountByAttributeAndExtensionValue() throws Exception {
" s.oid, s.fullObject, s.stringsCount, s.longsCount, s.datesCount, s.referencesCount, s.polysCount, s.booleansCount\n" +
"from\n" +
" RShadow s\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.name = :name )\n" +
" left join s.longs l with ( l.ownerType = :ownerType2 and l.name = :name2 )\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.item.name = :name )\n" +
" left join s.longs l with ( l.ownerType = :ownerType2 and l.item.name = :name2 )\n" +
"where\n" +
" (\n" +
" s2.value = :value and\n" +
Expand Down Expand Up @@ -621,8 +626,8 @@ public void test076QueryOrComposite() throws Exception {
" s.oid, s.fullObject, s.stringsCount, s.longsCount, s.datesCount, s.referencesCount, s.polysCount, s.booleansCount\n" +
"from\n" +
" RShadow s\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.name = :name )\n" +
" left join s.strings s3 with ( s3.ownerType = :ownerType2 and s3.name = :name2 )\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.item.name = :name )\n" +
" left join s.strings s3 with ( s3.ownerType = :ownerType2 and s3.item.name = :name2 )\n" +
"where\n" +
" (\n" +
" s.intent = :intent or\n" +
Expand Down Expand Up @@ -1098,7 +1103,7 @@ public void test130QueryAccountByAttributesAndResourceRef() throws Exception {
" s.booleansCount\n" +
"from\n" +
" RShadow s\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.name = :name )\n" +
" left join s.strings s2 with ( s2.ownerType = :ownerType and s2.item.name = :name )\n" +
"where\n" +
" (\n" +
" (\n" +
Expand Down Expand Up @@ -2690,7 +2695,7 @@ public void test580QueryObjectypeByTypeAndExtensionAttribute() throws Exception
" o.booleansCount\n" +
"from\n" +
" RObject o\n" +
" left join o.strings s with ( s.ownerType = :ownerType and s.name = :name )\n" +
" left join o.strings s with ( s.ownerType = :ownerType and s.item.name = :name )\n" +
"where\n" +
" (\n" +
" o.objectTypeClass = :objectTypeClass and\n" +
Expand Down Expand Up @@ -2961,7 +2966,7 @@ public void test620QueryGenericString() throws Exception {
" g.booleansCount\n" +
"from\n" +
" RGenericObject g\n" +
" left join g.strings s with ( s.ownerType = :ownerType and s.name = :name )\n" +
" left join g.strings s with ( s.ownerType = :ownerType and s.item.name = :name )\n" +
"where\n" +
" s.value = :value\n";
assertEqualsIgnoreWhitespace(expected, real);
Expand Down Expand Up @@ -3034,7 +3039,7 @@ public void test630QueryGenericBoolean() throws Exception {
" g.booleansCount\n" +
"from\n" +
" RGenericObject g\n" +
" left join g.booleans b with ( b.ownerType = :ownerType and b.name = :name )\n" +
" left join g.booleans b with ( b.ownerType = :ownerType and b.item.name = :name )\n" +
"where\n" +
" b.value = :value\n";

Expand Down Expand Up @@ -3090,11 +3095,27 @@ public void test640queryAssignmentExtensionBoolean() throws Exception {
" RUser u\n" +
" left join u.assignments a with a.assignmentOwner = :assignmentOwner\n" +
" left join a.extension e\n" +
" left join e.booleans b with b.name = :name\n" +
" left join e.booleans b with b.item.name = :name\n" +
"where\n" +
" b.value = :value";
assertEqualsIgnoreWhitespace(expected, real);

// include dependency on for this code org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
// CriteriaQuery<RAssignment> aQ = session.getCriteriaBuilder().createQuery(RAssignment.class);
// aQ.select(aQ.from(RAssignment.class));
// List<RAssignment> aList = session.createQuery(aQ).getResultList();
// System.out.println("RAssignment: " + aList);
//
// CriteriaQuery<RAssignmentExtension> aeQ = session.getCriteriaBuilder().createQuery(RAssignmentExtension.class);
// aeQ.select(aeQ.from(RAssignmentExtension.class));
// List<RAssignmentExtension> aeList = session.createQuery(aeQ).getResultList();
// System.out.println("RAssignmentExtension: " + aeList);
//
// CriteriaQuery<RAExtBoolean> aebQ = session.getCriteriaBuilder().createQuery(RAExtBoolean.class);
// aebQ.select(aebQ.from(RAExtBoolean.class));
// List<RAExtBoolean> aebList = session.createQuery(aebQ).getResultList();
// System.out.println("RAExtBoolean: " + aebList);
//
OperationResult result = new OperationResult("search");
List<PrismObject<UserType>> objects = repositoryService.searchObjects(UserType.class,
objectQuery, null, result);
Expand Down Expand Up @@ -3137,7 +3158,7 @@ public void test650QueryExtensionEnum() throws Exception {
+ " RUser u\n"
+ " left join u.strings s with (\n"
+ " s.ownerType = :ownerType and\n"
+ " s.name = :name\n"
+ " s.item.name = :name\n"
+ ")\n"
+ "where\n"
+ " s.value = :value\n";
Expand Down Expand Up @@ -3168,7 +3189,7 @@ public void test660QueryExtensionRef() throws Exception {
+ " RGenericObject g\n"
+ " left join g.references r with (\n"
+ " r.ownerType = :ownerType and\n"
+ " r.name = :name\n"
+ " r.item.name = :name\n"
+ " )\n"
+ "where\n"
+ " (\n"
Expand Down
Expand Up @@ -196,7 +196,7 @@ public void testExtensionEnum() throws Exception {


RAnyConverter converter = new RAnyConverter(prismContext);
Set<RAnyValue> values = converter.convertToRValue(item, false);
Set<RAnyValue<?>> values = converter.convertToRValue(item, false, session);

AssertJUnit.assertEquals("Expected only one enum value, but was " + values.size(), 1, values.size());

Expand Down
Expand Up @@ -71,6 +71,7 @@ private void createSQLSchema(String fileName, String dialect) {
SchemaExport export = new SchemaExport();
export.setOutputFile(fileName);
export.setDelimiter(";");
export.setFormat(true);
export.execute(EnumSet.of(TargetType.SCRIPT), SchemaExport.Action.CREATE, metadata.buildMetadata());
}

Expand Down
25 changes: 25 additions & 0 deletions repo/repo-sql-impl-test/src/test/resources/basic/user0.xml
@@ -0,0 +1,25 @@
<?xml version="1.0"?>
<!--
~ Copyright (c) 2010-2018 Evolveum
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<user>
<name>user0</name>
<assignment id="1">
<extension>
<skipAutogeneration>true</skipAutogeneration>
</extension>
</assignment>
</user>

0 comments on commit 974f3f5

Please sign in to comment.