/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portlet.messageboards.service; import com.liferay.message.boards.kernel.model.MBCategory; import com.liferay.message.boards.kernel.model.MBCategoryConstants; import com.liferay.message.boards.kernel.model.MBMessage; import com.liferay.message.boards.kernel.model.MBMessageConstants; import com.liferay.message.boards.kernel.service.MBCategoryServiceUtil; import com.liferay.message.boards.kernel.service.MBMessageLocalServiceUtil; import com.liferay.message.boards.kernel.service.MBMessageServiceUtil; import com.liferay.portal.kernel.dao.db.DB; import com.liferay.portal.kernel.dao.db.DBManagerUtil; import com.liferay.portal.kernel.dao.db.DBType; import com.liferay.portal.kernel.messaging.SynchronousDestination; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.security.permission.ActionKeys; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.UserLocalServiceUtil; import com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl; import com.liferay.portal.kernel.test.rule.AggregateTestRule; import com.liferay.portal.kernel.test.rule.DeleteAfterTestRun; import com.liferay.portal.kernel.test.rule.Sync; import com.liferay.portal.kernel.test.rule.SynchronousDestinationTestRule; import com.liferay.portal.kernel.test.util.GroupTestUtil; import com.liferay.portal.kernel.test.util.ServiceContextTestUtil; import com.liferay.portal.kernel.test.util.UserTestUtil; import com.liferay.portal.kernel.util.ObjectValuePair; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.security.permission.DoAsUserThread; import com.liferay.portal.service.test.ServiceTestUtil; import com.liferay.portal.spring.transaction.DefaultTransactionExecutor; import com.liferay.portal.test.log.CaptureAppender; import com.liferay.portal.test.log.Log4JLoggerTestUtil; import com.liferay.portal.test.rule.LiferayIntegrationTestRule; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Level; import org.apache.log4j.spi.LoggingEvent; import org.hibernate.util.JDBCExceptionReporter; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; /** * @author Alexander Chow */ @Sync public class MBMessageServiceTest { @ClassRule @Rule public static final AggregateTestRule aggregateTestRule = new AggregateTestRule( new LiferayIntegrationTestRule(), SynchronousDestinationTestRule.INSTANCE); @Before public void setUp() throws Exception { String name = "Test Category"; String description = "This is a test category."; String displayStyle = MBCategoryConstants.DEFAULT_DISPLAY_STYLE; String emailAddress = null; String inProtocol = null; String inServerName = null; int inServerPort = 0; boolean inUseSSL = false; String inUserName = null; String inPassword = null; int inReadInterval = 0; String outEmailAddress = null; boolean outCustom = false; String outServerName = null; int outServerPort = 0; boolean outUseSSL = false; String outUserName = null; String outPassword = null; boolean allowAnonymous = false; boolean mailingListActive = false; _group = GroupTestUtil.addGroup(); for (int i = 0; i < ServiceTestUtil.THREAD_COUNT; i++) { UserTestUtil.addUser(_group.getGroupId()); } ServiceContext serviceContext = ServiceContextTestUtil.getServiceContext(_group.getGroupId()); serviceContext.setGroupPermissions( new String[] {ActionKeys.ADD_MESSAGE, ActionKeys.VIEW}); serviceContext.setGuestPermissions( new String[] {ActionKeys.ADD_MESSAGE, ActionKeys.VIEW}); _category = MBCategoryServiceUtil.addCategory( MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID, name, description, displayStyle, emailAddress, inProtocol, inServerName, inServerPort, inUseSSL, inUserName, inPassword, inReadInterval, outEmailAddress, outCustom, outServerName, outServerPort, outUseSSL, outUserName, outPassword, allowAnonymous, mailingListActive, serviceContext); _userIds = UserLocalServiceUtil.getGroupUserIds(_group.getGroupId()); } @Test public void testAddMessagesConcurrently() throws Exception { DoAsUserThread[] doAsUserThreads = new DoAsUserThread[_userIds.length]; for (int i = 0; i < doAsUserThreads.length; i++) { String subject = "Test Message " + i; doAsUserThreads[i] = new AddMessageThread(_userIds[i], subject); } try (CaptureAppender captureAppender1 = Log4JLoggerTestUtil.configureLog4JLogger( BasePersistenceImpl.class.getName(), Level.ERROR); CaptureAppender captureAppender2 = Log4JLoggerTestUtil.configureLog4JLogger( DefaultTransactionExecutor.class.getName(), Level.ERROR); CaptureAppender captureAppender3 = Log4JLoggerTestUtil.configureLog4JLogger( DoAsUserThread.class.getName(), Level.ERROR); CaptureAppender captureAppender4 = Log4JLoggerTestUtil.configureLog4JLogger( JDBCExceptionReporter.class.getName(), Level.ERROR); CaptureAppender captureAppender5 = Log4JLoggerTestUtil.configureLog4JLogger( SynchronousDestination.class.getName(), Level.ERROR);) { for (DoAsUserThread doAsUserThread : doAsUserThreads) { doAsUserThread.start(); } for (DoAsUserThread doAsUserThread : doAsUserThreads) { doAsUserThread.join(); } DB db = DBManagerUtil.getDB(); if (db.getDBType() == DBType.HYPERSONIC) { for (LoggingEvent loggingEvent : captureAppender2.getLoggingEvents()) { String message = loggingEvent.getRenderedMessage(); Assert.assertTrue( message.startsWith( "Application exception overridden by commit " + "exception")); } for (LoggingEvent loggingEvent : captureAppender5.getLoggingEvents()) { String message = loggingEvent.getRenderedMessage(); Assert.assertTrue( message.startsWith("Unable to process message")); } } else if (db.getDBType() == DBType.SYBASE) { for (LoggingEvent loggingEvent : captureAppender1.getLoggingEvents()) { String message = loggingEvent.getRenderedMessage(); Assert.assertTrue( message.startsWith("Caught unexpected exception")); } for (LoggingEvent loggingEvent : captureAppender3.getLoggingEvents()) { String message = loggingEvent.getRenderedMessage(); StringBundler sb = new StringBundler(); sb.append("com.liferay.portal.kernel.exception."); sb.append("SystemException:"); Assert.assertTrue(message.startsWith(sb.toString())); } for (LoggingEvent loggingEvent : captureAppender4.getLoggingEvents()) { String message = loggingEvent.getRenderedMessage(); Assert.assertTrue(message.contains("Your server command")); Assert.assertTrue( message.contains( "encountered a deadlock situation. Please re-run " + "your command.")); } } } int successCount = 0; for (DoAsUserThread doAsUserThread : doAsUserThreads) { if (doAsUserThread.isSuccess()) { successCount++; } } Assert.assertTrue( "Only " + successCount + " out of " + _userIds.length + " threads added messages successfully", successCount == _userIds.length); } private MBCategory _category; @DeleteAfterTestRun private Group _group; private long[] _userIds; private class AddMessageThread extends DoAsUserThread { public AddMessageThread(long userId, String subject) { super(userId, ServiceTestUtil.RETRY_COUNT); _subject = subject; } @Override protected void doRun() throws Exception { String body = "This is a test message."; List<ObjectValuePair<String, InputStream>> inputStreamOVPs = new ArrayList<>(); boolean anonymous = false; double priority = 0.0; boolean allowPingbacks = false; ServiceContext serviceContext = new ServiceContext(); serviceContext.setAddGroupPermissions(true); serviceContext.setAddGuestPermissions(true); MBMessage mbMessage = MBMessageServiceUtil.addMessage( _category.getGroupId(), _category.getCategoryId(), _subject, body, MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, anonymous, priority, allowPingbacks, serviceContext); MBMessageLocalServiceUtil.deleteMessage(mbMessage); } private final String _subject; } }