0

I am looking to migrate data from one of the legacy database to one of Liferay tables. I can write the migration script, but I was wondering if there will be some issue with "Counter" service of liferay.

For example I have legacy custom user table. I need to move the users inside this table to Liferay's User_ table. I can use sql script to move the data. I am wondering what happens with primary key. As far as I know Liferay has counter service to create primary key and keep track of current id.

So while migrating is there anything that I need to do so that the Counter is not messed up after migration.

Sandeep Nair
  • 3,630
  • 3
  • 26
  • 38

3 Answers3

0

There are more issues than just the counter. You should strictly use Liferay's API to import the content.

I could name a few potential issues to pay attention to, but this will probably miss a few more - however it'd make you (or others reading this answer) confident that they now can cope with all issues. You can't. Don't go there. Simply use the API and it will take care of updating all the required dependencies. Plus, the API makes obvious what other data you still need in conjunction with your imported data.

Anybody who describes with more detail will set you up for disaster. And we've seen people who discovered their disasters more than 6 months after their manual writing to the database (in a particular case with running into duplicate primary keys, e.g. specifically the counter that you mention). Any of the possible failures might bring down your portal from one second to the other when you've long forgotten that you (or someone else) manually wrote to the database.

Olaf Kock
  • 46,930
  • 8
  • 59
  • 90
  • Thanks for the answer. How do you suggest to handle the transaction if there are more than one table to be updated. If i write the code in LocalServiceImpl class and call all other entities LocalServiceUtil classes will it take care of transaction or should I use BatchSessionUtil that Liferay has – Sandeep Nair May 12 '15 at 05:27
0

You could migrate data from a legacy database with Pentaho Data Integration by calling a REST endpoint (defined through {MODEL_NAME}ServiceImpl.java) that returns a counter increment of the entity I want to insert the data to. You would just have to respect using the same counter for each entity that is getting the new id's.

elabx
  • 31
  • 5
0

You can loop from list of legacy user, and do create Liferay users by using this class:

package com.yourcompany.yourapp.util;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.OrderFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.model.Account;
import com.liferay.portal.model.ClassName;
import com.liferay.portal.model.Company;
import com.liferay.portal.model.Contact;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.LayoutSet;
import com.liferay.portal.model.User;
import com.liferay.portal.security.permission.PermissionChecker;
import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
import com.liferay.portal.security.permission.PermissionThreadLocal;
import com.liferay.portal.service.AccountLocalServiceUtil;
import com.liferay.portal.service.ClassNameLocalServiceUtil;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.portal.service.ContactLocalServiceUtil;
import com.liferay.portal.service.GroupLocalServiceUtil;
import com.liferay.portal.service.LayoutSetLocalServiceUtil;
import com.liferay.portal.service.RoleLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portlet.asset.model.AssetEntry;
import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;

public class UserUtil {

    private static final Logger logger = Logger.getLogger(UserUtil.class);

    private long companyId;
    private long creatorUserId;
    private long accountId;
    private Date date;

    public UserUtil() {
        try {
            DynamicQuery queryCompany = DynamicQueryFactoryUtil.forClass(Company.class)
                    .addOrder(OrderFactoryUtil.asc("companyId"));
            List<Company> listCompany = (List<Company>) CompanyLocalServiceUtil.dynamicQuery(queryCompany, 0, 1);
            companyId = listCompany.get(0).getCompanyId();
            //-----------
            DynamicQuery queryAccount = DynamicQueryFactoryUtil.forClass(Account.class)
                    .addOrder(OrderFactoryUtil.asc("accountId"));
            List<Account> listAccount = (List<Account>) AccountLocalServiceUtil.dynamicQuery(queryAccount, 0, 1);
            accountId = listAccount.get(0).getAccountId();
            //-----------
            DynamicQuery queryUser = DynamicQueryFactoryUtil.forClass(User.class)
                    .add(PropertyFactoryUtil.forName("defaultUser").eq(false))
                    .addOrder(OrderFactoryUtil.asc("createDate"));
            List<User> listUser = (List<User>) UserLocalServiceUtil.dynamicQuery(queryUser, 0, 1);
            creatorUserId = listUser.get(0).getUserId();
            date = new Date();
        } catch (SystemException ex) {
            logger.error(ex.getMessage());
        }
    }

    public void create(String screenName, String emailAddress, String hashedPassword, String fullName) {
        try {
            long contactId = CounterLocalServiceUtil.increment();//or use Contact.class.getName() as param
            Contact contact = ContactLocalServiceUtil.createContact(contactId);
            contact.setAccountId(accountId);
            //contact.setBirthday(DateUtil.getDate("dd MM yyyy", "01 11 1986"));
            contact.setCachedModel(true);
            contact.setCompanyId(companyId);
            contact.setCreateDate(date);
            contact.setEmailAddress(emailAddress);
            //contact.setEmployeeNumber(employeeNumber);
            //contact.setEmployeeStatusId(employeeStatusId);
            contact.setFirstName(fullName);
            contact.setMale(true);
            contact.setNew(true);
            //contact.setUserId(creatorUserId);
            User creatorUser = UserLocalServiceUtil.getUserById(creatorUserId);
            contact.setUserName(creatorUser.getFullName());
            contact.setUserUuid(creatorUser.getUuid());
            ContactLocalServiceUtil.addContact(contact);
            //----------------------
            long userId = CounterLocalServiceUtil.increment();//or use User.class.getName() as param
            //----------------------
            User user = UserLocalServiceUtil.createUser(userId);
            user.setAgreedToTermsOfUse(true);
            user.setCachedModel(true);
            user.setCompanyId(companyId);
            user.setContactId(contactId);
            user.setCreateDate(date);
            user.setDefaultUser(false);
            user.setDigest(null);
            user.setEmailAddress(emailAddress);
            user.setEmailAddressVerified(true);
            user.setFirstName(fullName);
            user.setGreeting("Hi " + user.getFirstName());
            user.setLanguageId("en_US");
            user.setModifiedDate(date);
            user.setNew(true);
            user.setPassword(hashedPassword);
            user.setPasswordEncrypted(true);
            user.setPasswordReset(false);
            //user.setPasswordUnencrypted();
            user.setScreenName(screenName);
            user.setStatus(WorkflowConstants.STATUS_APPROVED);
            user.setTimeZoneId("UTC+7");
            user.setUserUuid(creatorUser.getUuid());
            user.setUuid(PortalUUIDUtil.generate());
            UserLocalServiceUtil.addUser(user);
            //----------------------
            try {
                // to avoid "PermissionChecker not Initialized"
                PermissionChecker checker = PermissionCheckerFactoryUtil.create(creatorUser);
                PermissionThreadLocal.setPermissionChecker(checker);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
            //----------------------
            ClassName clsNameUser = ClassNameLocalServiceUtil.getClassName(Constants.USER_CLASS);
            long classNameId = clsNameUser.getClassNameId();
            long groupId = CounterLocalServiceUtil.increment();// or use Group.class.getName() as param
            Group group = GroupLocalServiceUtil.createGroup(groupId);
            group.setActive(true);
            group.setCachedModel(true);
            group.setClassNameId(classNameId);
            group.setClassPK(userId);
            group.setCompanyId(companyId);
            group.setCreatorUserId(creatorUser.getUserId());
            group.setCreatorUserUuid(creatorUser.getUuid());
            group.setFriendlyURL(String.valueOf(userId));
            group.setName(String.valueOf(userId));
            group.setNew(true);
            group.setSite(false);
            group.setTreePath("/" + groupId + "/");
            group.setType(0);
            group.setUuid(PortalUUIDUtil.generate());
            GroupLocalServiceUtil.addGroup(group);
            //-----------------------------
            long layoutSetId1 = CounterLocalServiceUtil.increment();//or use LayoutSet.class.getName() as param
            LayoutSet layoutSet1 = LayoutSetLocalServiceUtil.createLayoutSet(layoutSetId1);
            layoutSet1.setCachedModel(true);
            //layoutSet.setColorSchemeId(colorSchemeId);
            layoutSet1.setCompanyId(companyId);
            layoutSet1.setCreateDate(date);
            //layoutSet.setCss(css);
            layoutSet1.setGroupId(groupId);
            //layoutSet.setLogo(logo);
            //layoutSet.setLogoId(logoId);
            layoutSet1.setModifiedDate(date);
            layoutSet1.setNew(true);
            layoutSet1.setPrivateLayout(true);
            //layoutSet.setThemeId(themeId);
            LayoutSetLocalServiceUtil.addLayoutSet(layoutSet1);
            //-----------------------------
            long layoutSetId2 = CounterLocalServiceUtil.increment();// or use LayoutSet.class.getName() as param
            LayoutSet layoutSet2 = LayoutSetLocalServiceUtil.getLayoutSet(layoutSetId1);
            layoutSet2.setLayoutSetId(layoutSetId2);
            layoutSet2.setPrivateLayout(false);
            LayoutSetLocalServiceUtil.addLayoutSet(layoutSet2);
            //-----------------------------
            long assetEntryId = CounterLocalServiceUtil.increment();//or use AssetEntry.class.getName() as param
            AssetEntry assetEntry = AssetEntryLocalServiceUtil.createAssetEntry(assetEntryId);
            assetEntry.setCompanyId(companyId);
            assetEntry.setClassPK(userId);
            assetEntry.setGroupId(groupId);
            assetEntry.setClassNameId(classNameId);
            //ae.setTitle(title);
            assetEntry.setUserId(userId);
            AssetEntryLocalServiceUtil.addAssetEntry(assetEntry);
            //--------------------------------------------------
            //long orgAdminRoleId = RoleLocalServiceUtil.getRole(companyId, Constants.ORG_ADMIN_ROLE_NAME).getRoleId();
            //UserGroupRoleLocalServiceUtil.addUserGroupRoles(userId, groupId, new long[] { orgAdminRoleId });
            long orgUserRoleId = RoleLocalServiceUtil.getRole(companyId, Constants.ORG_USER_ROLE_NAME).getRoleId();
            RoleLocalServiceUtil.addUserRole(userId, orgUserRoleId);
            long siteMemberRoleId = RoleLocalServiceUtil.getRole(companyId, Constants.SITE_MEMBER_ROLE_NAME).getRoleId();
            RoleLocalServiceUtil.addUserRole(userId, siteMemberRoleId);
            //-----------------------------------------------------------
        } catch (SystemException | PortalException ex) {
            logger.error(ex.getMessage(), ex);
        }
    }
}

then you can create new instance of UserUtil and call method create() inside your loop of legacy user list, something like this:

UserUtil userUtil = new UserUtil();
for (LegacyUser user : listOfLegacyUser) {
    userUtil.create(........);
}

note that hashedPassword depends on what your hash method is, defined in portal-ext.properties, default value is: passwords.ecnryption.algorithm=PBKDF2WithHmacSHA1/160/128000 but you can use one of values below:

passwords.encryption.algorithm=BCRYPT/10
passwords.encryption.algorithm=MD2
passwords.encryption.algorithm=MD5
passwords.encryption.algorithm=NONE
passwords.encryption.algorithm=PBKDF2WithHmacSHA1/160/128000
passwords.encryption.algorithm=SHA
passwords.encryption.algorithm=SHA-256
passwords.encryption.algorithm=SHA-384
passwords.encryption.algorithm=SSHA
passwords.encryption.algorithm=UFC-CRYPT
danisupr4
  • 815
  • 1
  • 9
  • 22