@Test public void whenTraceOnMixinImplExpectTwoEntryInEntityStore() throws Exception { SomeService sc = moduleInstance.serviceFinder().<SomeService>findService(SomeService.class).get(); assertEquals(123, sc.doSomethingImportant()); assertEquals(789, sc.doSomethingModeratelyImportant()); UnitOfWork uow = unitOfWorkFactory.newUnitOfWork(); try { QueryBuilder<TraceRecord> builder = queryBuilderFactory.newQueryBuilder(TraceRecord.class); Query<TraceRecord> query = builder.newQuery(uow); // IS sorting needed?? TraceRecord template = templateFor(TraceRecord.class); query.orderBy(orderBy(template.methodName())); Iterator<TraceRecord> result = query.iterator(); assertTrue(result.hasNext()); TraceRecord rec1 = result.next(); assertEquals("doSomethingImportant", rec1.methodName().get()); assertTrue(result.hasNext()); TraceRecord rec2 = result.next(); assertEquals("doSomethingModeratelyImportant", rec2.methodName().get()); assertFalse(result.hasNext()); uow.complete(); } catch (Exception e) { uow.discard(); throw e; } catch (Error e) { uow.discard(); throw e; } }
// WARN Watch this code, see if we can do better, maybe leverage @UnitOfWorkRetry @Override public void run() { System.out.println("Running Schedule"); Usecase usecase = UsecaseBuilder.newUsecase("ScheduleRunner"); UnitOfWork uow = module.newUnitOfWork(usecase); try { Schedule schedule = uow.get(Schedule.class, this.schedule.scheduleIdentity); Task task = schedule.task().get(); schedule = uow.get(Schedule.class, this.schedule.scheduleIdentity); try { schedule.taskStarting(); task.run(); schedule.taskCompletedSuccessfully(); } catch (RuntimeException ex) { schedule.taskCompletedWithException(ex); } schedulerMixin.dispatchForExecution(schedule); uow.complete(); } catch (UnitOfWorkCompletionException ex) { } finally { // What should we do if we can't manage the Running flag?? if (uow.isOpen()) { uow.discard(); } } }
private static void buildDemoNetwork(SingletonAssembler assembler) throws Exception { UnitOfWork uow = assembler.unitOfWorkFactory().newUnitOfWork(newUsecase("Build demo network of activities")); try { // try different combinations here... ActivityEntity a = uow.newEntity(ActivityEntity.class, "A"); ActivityEntity b = uow.newEntity(ActivityEntity.class, "B"); ActivityEntity c = uow.newEntity(ActivityEntity.class, "C"); ActivityEntity d = uow.newEntity(ActivityEntity.class, "D"); a.duration().set(2); b.duration().set(7); c.duration().set(3); d.duration().set(2); a.succeededBy(c, d); // Try different variations: b.succeededBy(d); // "Original" // b.succeededBy( c ); // Variation // c.succeededBy( a ); // "C" already planned // d.succeededBy( a ); // Cyclic dependency ProjectData project = uow.newEntity(ProjectData.class, PROJECT); // project.addActivities( a, b, c, d ); project.addActivities(d, c, b, a); // More interesting execution flow // Save uow.complete(); } catch (Exception e) { uow.discard(); throw e; } }
@Override public void tearDown() throws Exception { if (module.isUnitOfWorkActive()) { UnitOfWork uow = module.currentUnitOfWork(); uow.discard(); } super.tearDown(); }
@Override public synchronized void refresh() { if (configuration != null) { configuration = null; uow.discard(); uow = null; } }
@Test public void payAllBills() throws Exception { UnitOfWork uow = module.newUnitOfWork(newUsecase("Pay all bills from checking to creditors")); try { BalanceData source = uow.get(BalanceData.class, CHECKING_ACCOUNT_ID); PayBillsContext2 context = module.newObject(PayBillsContext2.class); context.bind(source).payBills(); } finally { uow.discard(); } }
public Subject authenticate(Object credentials) { UnitOfWork unitOfWork = module .unitOfWorkFactory() .newUnitOfWork(UsecaseBuilder.newUsecase("Authenticate JMX user")); Subject subject = null; try { if (!(credentials instanceof String[])) { // Special case for null so we get a more informative message if (credentials == null) { throw new SecurityException("Credentials required"); } throw new SecurityException("Credentials should be String[]"); } final String[] aCredentials = (String[]) credentials; if (aCredentials.length != 2) { throw new SecurityException("Credentials should have 2 elements"); } String username = aCredentials[0]; String password = aCredentials[1]; Authentication user = unitOfWork.get(Authentication.class, username); if (!user.login(password)) { throw new SecurityException("User/password combination not valid."); } if (((UserAuthentication.Data) user).isAdministrator()) { subject = new Subject( true, Collections.singleton(new JMXPrincipal(username)), Collections.EMPTY_SET, Collections.EMPTY_SET); } else { throw new SecurityException("Invalid credentials"); } unitOfWork.complete(); } catch (Throwable e) { unitOfWork.discard(); throw new SecurityException(e); } return subject; }
@Test public void givenEntityWithImmutableAssociationWhenBuildingThenNoException() throws Exception { UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork(); try { PersonEntity father = unitOfWork.newEntity(PersonEntity.class); EntityBuilder<PersonEntity> builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity instance = builder.instance(); instance.father().set(father); PersonEntity child = builder.newInstance(); } finally { unitOfWork.discard(); } }
@Test public void testOperators() throws UnitOfWorkCompletionException, ActivationException, AssemblyException { SingletonAssembler assembler = new SingletonAssembler() { @Override public void assemble(ModuleAssembly module) throws AssemblyException { new EntityTestAssembler().assemble(module); module.entities(TestEntity.class); module.values(TestValue.class); module.forMixin(TestEntity.class).declareDefaults().foo().set("Bar"); module.forMixin(TestValue.class).declareDefaults().bar().set("Xyz"); } }; UnitOfWork uow = assembler.module().newUnitOfWork(); try { EntityBuilder<TestEntity> entityBuilder = uow.newEntityBuilder(TestEntity.class, "123"); entityBuilder.instance().value().set(assembler.module().newValue(TestValue.class)); TestEntity testEntity = entityBuilder.newInstance(); uow.complete(); uow = assembler.module().newUnitOfWork(); Iterable<TestEntity> entities = Iterables.iterable(testEntity = uow.get(testEntity)); QueryBuilder<TestEntity> builder = assembler.module().newQueryBuilder(TestEntity.class); { Specification<Composite> where = QueryExpressions.eq(QueryExpressions.templateFor(TestEntity.class).foo(), "Bar"); Assert.assertTrue(where.satisfiedBy(testEntity)); System.out.println(where); } { Specification<Composite> where = QueryExpressions.eq( QueryExpressions.templateFor(TestEntity.class).value().get().bar(), "Xyz"); Assert.assertTrue(where.satisfiedBy(testEntity)); System.out.println(where); Assert.assertTrue(builder.where(where).newQuery(entities).find().equals(testEntity)); } } finally { uow.discard(); } }
@Test public void planActivitiesTest() throws Exception { UnitOfWork uow = assembler.unitOfWorkFactory().newUnitOfWork(UsecaseBuilder.newUsecase("Test")); try { ProjectData project = uow.get(ProjectData.class, PROJECT); new FrontloadContext(project).frontloadNetworkFrom(1); // try 2 uow.complete(); } catch (Exception e) { uow.discard(); throw e; } }
private void printBalances() { UnitOfWork uow = module.newUnitOfWork(UsecaseBuilder.newUsecase("Print balances")); try { System.out.println( SAVINGS_ACCOUNT_ID + ":" + uow.get(BalanceData.class, SAVINGS_ACCOUNT_ID).getBalance()); System.out.println( CHECKING_ACCOUNT_ID + ":" + uow.get(BalanceData.class, CHECKING_ACCOUNT_ID).getBalance()); System.out.println( CREDITOR_ID1 + ":" + uow.get(BalanceData.class, CREDITOR_ID1).getBalance()); System.out.println( CREDITOR_ID2 + ":" + uow.get(BalanceData.class, CREDITOR_ID2).getBalance()); } finally { uow.discard(); } }
@Test public void givenEntityWithImmutableManyAssociationWhenBuildingThenNoException() throws Exception { UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork(); try { EntityBuilder<PersonEntity> builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity person1 = builder.instance(); person1 = builder.newInstance(); builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity person2 = builder.instance(); person2.colleagues().add(0, person1); person2 = builder.newInstance(); } finally { unitOfWork.discard(); } }
private void loadSchedules() throws UnitOfWorkCompletionException { UnitOfWork uow = module.newUnitOfWork(); try { Schedules schedules = uow.get(Schedules.class, getSchedulesIdentity(me)); for (Schedule schedule : schedules.schedules()) { dispatchForExecution(schedule); } } catch (NoSuchEntityException e) { // Create a new Schedules entity for keeping track of them all. uow.newEntity(Schedules.class, getSchedulesIdentity(me)); uow.complete(); } finally { if (uow.isOpen()) { uow.discard(); } } }
@Test public void createAndModifyEntity() throws Exception { UnitOfWork uow = this.module.newUnitOfWork(); TestEntity entity = uow.newEntity(TestEntity.class); uow.complete(); uow = this.module.newUnitOfWork(); entity = uow.get(entity); entity.testString().set("NewTestString"); uow.complete(); uow = this.module.newUnitOfWork(); entity = uow.get(entity); Assert.assertEquals( "New value did not store in indexing.", "NewTestString", entity.testString().get()); uow.discard(); }
@Test public void testEntity() throws UnitOfWorkCompletionException, IOException { SingletonAssembler assembler = new SingletonAssembler() { @Override public void assemble(ModuleAssembly module) throws AssemblyException { module.entities(TestEntity.class).withMixins(ScalaTraitMixin.class); module.services(TestService.class).withMixins(ScalaTraitMixin.class); new EntityTestAssembler().assemble(module); new RdfMemoryStoreAssembler().assemble(module); } }; // Create and update Entity UnitOfWork uow = assembler.module().newUnitOfWork(); try { Commands entity = uow.newEntity(Commands.class); entity.updateFoo("Foo"); Data data = uow.get(Data.class, entity.toString()); Assert.assertEquals("FooFoo", data.foo().get()); } finally { uow.complete(); } assembler.module().findService(IndexExporter.class).get().exportReadableToStream(System.out); // Find it uow = assembler.module().newUnitOfWork(); try { Data data = uow.newQuery( assembler .module() .newQueryBuilder(Data.class) .where(eq(templateFor(Data.class).foo(), "FooFoo"))) .find(); Assert.assertEquals("FooFoo", data.foo().get()); } finally { uow.discard(); } }
public void activate() throws Exception { UnitOfWork unitOfWork = uowf.newUnitOfWork(); try { { ValueBuilder<TestValue> valueBuilder = vbf.newValueBuilder(TestValue.class); valueBuilder.prototype().longList().get().add(42L); valueBuilder.prototype().string().set("Foo bar value"); valueBuilder.prototype().map().set(new HashMap()); EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder(TestEntity.class, "test1"); builder.instance().name().set("Foo bar"); builder.instance().age().set(42); builder.instance().value().set(valueBuilder.newInstance()); TestEntity testEntity = builder.newInstance(); EntityBuilder<TestEntity> builder2 = unitOfWork.newEntityBuilder(TestEntity.class, "test2"); builder2.instance().name().set("Xyzzy"); builder2.instance().age().set(12); builder2.instance().association().set(testEntity); builder2.instance().manyAssociation().add(0, testEntity); builder2.instance().manyAssociation().add(0, testEntity); EntityBuilder<TestRole> builder3 = unitOfWork.newEntityBuilder(TestRole.class); builder3.instance().name().set("A role"); TestRole testRole = builder3.newInstance(); builder2.newInstance(); } { EntityBuilder<TestEntity2> builder = unitOfWork.newEntityBuilder(TestEntity2.class, "test3"); builder.instance().name().set("Test3"); builder.newInstance(); } unitOfWork.complete(); } catch (Exception e) { unitOfWork.discard(); throw e; } }
@After public void printResult() throws Exception { UnitOfWork uow = assembler.unitOfWorkFactory().newUnitOfWork(newUsecase("Print Gantt chart")); try { List<ActivityData> activities = uow.get(ProjectData.class, PROJECT).allActivities(); StringBuilder sb = new StringBuilder(); sb.append("\n\n### Gantt chart showing planned activities:\n"); Collections.sort( activities, new Comparator<ActivityData>() { public int compare(ActivityData a1, ActivityData a2) { if (a1.earlyStart().get().equals(a2.earlyStart().get())) return getEntityReference(a1) .identity() .compareTo(getEntityReference(a2).identity()); else return a1.earlyStart().get() - a2.earlyStart().get(); } }); for (ActivityData activity : activities) { String id = EntityReference.getEntityReference(activity).identity(); Integer start = activity.earlyStart().get(); Integer duration = activity.duration().get(); for (int i = 1; i < start; i++) { sb.append(" "); } sb.append(id); for (int i = 0; i < duration - 1; i++) { sb.append(" ="); } sb.append("\n"); } sb.append("1 2 3 4 5 6 7 8 9"); System.out.println(sb.toString()); } finally { uow.discard(); } System.out.println("----------------------------------------------------------"); }
@Test(expected = IllegalStateException.class) public void givenEntityWithImmutableAssociationWhenChangingValueThenThrowException() throws Exception { UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork(); try { EntityBuilder<PersonEntity> builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity father = builder.instance(); father = builder.newInstance(); builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity child = builder.instance(); child = builder.newInstance(); child.father().set(father); unitOfWork.complete(); } catch (Exception e) { unitOfWork.discard(); throw e; } }
@Test(expected = IllegalStateException.class) public void givenEntityWithImmutableManyAssociationWhenChangingValueThenThrowException() throws Exception { UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork(); try { EntityBuilder<PersonEntity> builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity person1 = builder.instance(); person1 = builder.newInstance(); builder = unitOfWork.newEntityBuilder(PersonEntity.class); PersonEntity person2 = builder.instance(); person2 = builder.newInstance(); person1.colleagues().add(0, person2); unitOfWork.complete(); } catch (Exception e) { unitOfWork.discard(); throw e; } }
private static void bootstrapData() throws Exception { UnitOfWork uow = module.newUnitOfWork(newUsecase("Bootstrap data")); try { SavingsAccountEntity account = uow.newEntity(SavingsAccountEntity.class, SAVINGS_ACCOUNT_ID); account.increasedBalance(1000); CheckingAccountEntity checkingAccount = uow.newEntity(CheckingAccountEntity.class, CHECKING_ACCOUNT_ID); checkingAccount.increasedBalance(200); // Create some creditor debt BalanceData bakerAccount = uow.newEntity(CreditorEntity.class, CREDITOR_ID1); bakerAccount.decreasedBalance(50); BalanceData butcherAccount = uow.newEntity(CreditorEntity.class, CREDITOR_ID2); butcherAccount.decreasedBalance(90); // Save uow.complete(); } finally { uow.discard(); } }
@Test(expected = IllegalArgumentException.class) public void transferTwiceOfMoneyFromSavingsToChecking() throws Exception { UnitOfWork uow = module.newUnitOfWork(UsecaseBuilder.newUsecase("Transfer from savings to checking")); try { // Select source and destination BalanceData source = uow.get(BalanceData.class, SAVINGS_ACCOUNT_ID); BalanceData destination = uow.get(BalanceData.class, CHECKING_ACCOUNT_ID); // Instantiate context and execute enactments with that context TransferMoneyContext2 context = module.newTransient(TransferMoneyContext2.class).bind(source, destination); // Query for double the balance final Integer amountToTransfer = context.availableFunds() * 2; // Transfer from savings to checking context.transfer(amountToTransfer); } finally { uow.discard(); } }
public void run() { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); if (!circuitBreaker.isOn()) return; // Don't try - circuit breaker is off boolean expunge = config.configuration().deleteMailOnInboxClose().get(); if (config.configuration().debug().get()) { logger.info("Checking email"); logger.info("Delete mail on close - " + expunge); } Session session = javax.mail.Session.getInstance(props, authenticator); session.setDebug(config.configuration().debug().get()); Usecase usecase = newUsecase("Receive Mail"); UnitOfWork uow = null; Store store = null; Folder inbox = null; Folder archive = null; boolean archiveExists = false; List<Message> copyToArchive = new ArrayList<Message>(); MimeMessage internalMessage = null; try { store = session.getStore(url); store.connect(); inbox = store.getFolder("INBOX"); inbox.open(Folder.READ_WRITE); javax.mail.Message[] messages = inbox.getMessages(); FetchProfile fp = new FetchProfile(); // fp.add( "In-Reply-To" ); inbox.fetch(messages, fp); // check if the archive folder is configured and exists if (!Strings.empty(config.configuration().archiveFolder().get()) && config.configuration().protocol().get().startsWith("imap")) { archive = store.getFolder(config.configuration().archiveFolder().get()); // if not exists - create if (!archive.exists()) { archive.create(Folder.HOLDS_MESSAGES); archiveExists = true; } else { archiveExists = true; } archive.open(Folder.READ_WRITE); } for (javax.mail.Message message : messages) { int tries = 0; while (tries < 3) { uow = module.unitOfWorkFactory().newUnitOfWork(usecase); ValueBuilder<EmailValue> builder = module.valueBuilderFactory().newValueBuilder(EmailValue.class); try { // Force a complete fetch of the message by cloning it to a internal MimeMessage // to avoid "javax.mail.MessagingException: Unable to load BODYSTRUCTURE" problems // f.ex. experienced if the message contains a windows .eml file as attachment! // Beware that all flag and folder operations have to be made on the original message // and not on the internal one!! internalMessage = new MimeMessage((MimeMessage) message); Object content = internalMessage.getContent(); // Get email fields builder .prototype() .from() .set(((InternetAddress) internalMessage.getFrom()[0]).getAddress()); builder .prototype() .fromName() .set(((InternetAddress) internalMessage.getFrom()[0]).getPersonal()); builder .prototype() .subject() .set(internalMessage.getSubject() == null ? "" : internalMessage.getSubject()); // Get headers for (Header header : Iterables.iterable((Enumeration<Header>) internalMessage.getAllHeaders())) { builder.prototype().headers().get().put(header.getName(), header.getValue()); } // Get all recipients in order - TO, CC, BCC // and provide it to the toaddress method to pick the first possible valid adress builder .prototype() .to() .set( toaddress( internalMessage.getAllRecipients(), builder.prototype().headers().get().get("References"))); builder.prototype().messageId().set(internalMessage.getHeader("Message-ID")[0]); // Get body and attachments String body = ""; // set content initially so it never can become null builder.prototype().content().set(body); if (content instanceof String) { body = content.toString(); builder.prototype().content().set(body); String contentTypeString = cleanContentType(internalMessage.getContentType()); builder.prototype().contentType().set(contentTypeString); if (Translator.HTML.equalsIgnoreCase(contentTypeString)) { builder.prototype().contentHtml().set(body); } } else if (content instanceof Multipart) { handleMultipart((Multipart) content, internalMessage, builder); } else if (content instanceof InputStream) { content = new MimeMessage(session, (InputStream) content).getContent(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Inputs.byteBuffer((InputStream) content, 4096).transferTo(Outputs.byteBuffer(baos)); String data = new String(baos.toByteArray(), "UTF-8"); // Unknown content type - abort // and create failure case String subj = "Unkonwn content type: " + internalMessage.getSubject(); builder .prototype() .subject() .set(subj.length() > 50 ? subj.substring(0, 50) : subj); builder.prototype().content().set(body); builder.prototype().contentType().set(internalMessage.getContentType()); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); copyToArchive.add(message); if (expunge) message.setFlag(Flags.Flag.DELETED, true); uow.discard(); tries = 3; continue; } else { // Unknown content type - abort // and create failure case String subj = "Unkonwn content type: " + internalMessage.getSubject(); builder .prototype() .subject() .set(subj.length() > 50 ? subj.substring(0, 50) : subj); builder.prototype().content().set(body); builder.prototype().contentType().set(internalMessage.getContentType()); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); copyToArchive.add(message); if (expunge) message.setFlag(Flags.Flag.DELETED, true); uow.discard(); logger.error( "Could not parse emails: unknown content type " + content.getClass().getName()); tries = 3; continue; } // make sure mail content fit's into statistic database - truncate on 65.500 // characters. if (builder.prototype().content().get().length() > 65000) { builder .prototype() .content() .set(builder.prototype().content().get().substring(0, 65000)); } // try to reveal if it is a smpt error we are looking at // X-Failed-Recipients is returned by Gmail // X-FC-MachineGenerated is returned by FirstClass // Exchange is following RFC 6522 - The Multipart/Report Media Type for // the Reporting of Mail System Administrative Messages boolean isSmtpErrorReport = !Strings.empty(builder.prototype().headers().get().get("X-Failed-Recipients")) || (!Strings.empty( builder.prototype().headers().get().get("X-FC-MachineGenerated")) && "true" .equals( builder.prototype().headers().get().get("X-FC-MachineGenerated"))) || !Strings.empty( new ContentType(builder.prototype().headers().get().get("Content-Type")) .getParameter("report-type")); if (isSmtpErrorReport) { // This is a mail bounce due to SMTP error - create support case. String subj = "Undeliverable mail: " + builder.prototype().subject().get(); builder .prototype() .subject() .set(subj.length() > 50 ? subj.substring(0, 50) : subj); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); copyToArchive.add(message); if (expunge) message.setFlag(Flags.Flag.DELETED, true); uow.discard(); logger.error("Received a mail bounce reply: " + body); tries = 3; continue; } if (builder.prototype().to().get().equals("n/a")) { // This is a mail has no to address - create support case. String subj = "No TO address: " + builder.prototype().subject().get(); builder .prototype() .subject() .set(subj.length() > 50 ? subj.substring(0, 50) : subj); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); copyToArchive.add(message); if (expunge) message.setFlag(Flags.Flag.DELETED, true); uow.discard(); logger.error("Received a mail without TO address: " + body); tries = 3; continue; } mailReceiver.receivedEmail(null, builder.newInstance()); try { logger.debug("This is try " + tries); uow.complete(); tries = 3; } catch (ConcurrentEntityModificationException ceme) { if (tries < 2) { logger.debug("Encountered ConcurrentEntityModificationException - try again "); // discard uow and try again uow.discard(); tries++; continue; } else { logger.debug("Rethrowing ConcurrentEntityModification.Exception"); tries++; throw ceme; } } copyToArchive.add(message); // remove mail on success if expunge is true if (expunge) message.setFlag(Flags.Flag.DELETED, true); } catch (Throwable e) { String subj = "Unknown error: " + internalMessage.getSubject(); builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj); StringBuilder content = new StringBuilder(); content.append("Error Message: " + e.getMessage()); content.append("\n\rStackTrace:\n\r"); for (StackTraceElement trace : Arrays.asList(e.getStackTrace())) { content.append(trace.toString() + "\n\r"); } builder.prototype().content().set(content.toString()); // since we create the content of the message our self it's ok to set content type // always to text/plain builder.prototype().contentType().set("text/plain"); // Make sure to address has some value before vi create a case!! if (builder.prototype().to().get() == null) { builder.prototype().to().set("n/a"); } systemDefaults.createCaseOnEmailFailure(builder.newInstance()); copyToArchive.add(message); if (expunge) message.setFlag(Flags.Flag.DELETED, true); uow.discard(); logger.error("Could not parse emails", e); tries = 3; } } } // copy message to archive if archive exists if (archiveExists) { inbox.copyMessages(copyToArchive.toArray(new Message[0]), archive); archive.close(false); } inbox.close(config.configuration().deleteMailOnInboxClose().get()); store.close(); if (config.configuration().debug().get()) { logger.info("Checked email"); } circuitBreaker.success(); } catch (Throwable e) { logger.error("Error in mail receiver: ", e); circuitBreaker.throwable(e); try { if (inbox != null && inbox.isOpen()) inbox.close(false); if (store != null && store.isConnected()) store.close(); } catch (Throwable e1) { logger.error("Could not close inbox", e1); } } }
public void activate() throws Exception { Usecase usecase = UsecaseBuilder.newUsecase("Populate Sample Voyages"); UnitOfWork uow = uowf.newUnitOfWork(usecase); try { final Location HONGKONG = locationRepository.findLocationByUnLocode("CNHKG"); final Location TOKYO = locationRepository.findLocationByUnLocode("JNTKO"); final Location NEWYORK = locationRepository.findLocationByUnLocode("USNYC"); final Location CHICAGO = locationRepository.findLocationByUnLocode("USCHI"); final Location STOCKHOLM = locationRepository.findLocationByUnLocode("SESTO"); final Location ROTTERDAM = locationRepository.findLocationByUnLocode("NLRTM"); final Location MELBOURNE = locationRepository.findLocationByUnLocode("AUMEL"); final Location HAMBURG = locationRepository.findLocationByUnLocode("DEHAM"); final Location HELSINKI = locationRepository.findLocationByUnLocode("FIHEL"); final Location DALLAS = locationRepository.findLocationByUnLocode("USDAL"); final Location HANGZOU = locationRepository.findLocationByUnLocode("CNHGH"); final Location SHANGHAI = locationRepository.findLocationByUnLocode("CNSHA"); Voyage v100 = new VoyageRepository.Builder(vbf, uow, "V100", HONGKONG) .addMovement(TOKYO, toDate("2009-03-03"), toDate("2009-03-05")) .addMovement(NEWYORK, toDate("2009-03-06"), toDate("2009-03-09")) .build(); Voyage v200 = new VoyageRepository.Builder(vbf, uow, "V200", TOKYO) .addMovement(NEWYORK, toDate("2009-03-06"), toDate("2009-03-08")) .addMovement(CHICAGO, toDate("2009-03-10"), toDate("2009-03-14")) .addMovement(STOCKHOLM, toDate("2009-03-14"), toDate("2009-03-16")) .build(); Voyage v300 = new VoyageRepository.Builder(vbf, uow, "V300", TOKYO) .addMovement(ROTTERDAM, toDate("2009-03-22"), toDate("2009-03-25")) .addMovement(HAMBURG, toDate("2009-03-25"), toDate("2009-03-26")) .addMovement(MELBOURNE, toDate("2009-03-28"), toDate("2009-04-03")) .addMovement(TOKYO, toDate("2009-04-03"), toDate("2009-04-06")) .build(); Voyage v400 = new VoyageRepository.Builder(vbf, uow, "V400", HAMBURG) .addMovement(STOCKHOLM, toDate("2009-03-14"), toDate("2009-03-15")) .addMovement(HELSINKI, toDate("2009-03-15"), toDate("2009-03-16")) .addMovement(HAMBURG, toDate("2009-03-20"), toDate("2009-03-22")) .build(); /* * Voyage number 0100S (by ship) * <p/> * Hongkong - Hangzou - Tokyo - Melbourne - New York */ Voyage HONGKONG_TO_NEW_YORK = new VoyageRepository.Builder(vbf, uow, "0100S", HONGKONG) .addMovement(HANGZOU, toDate("2008-10-01", "12:00"), toDate("2008-10-03", "14:30")) .addMovement(TOKYO, toDate("2008-10-03", "21:00"), toDate("2008-10-06", "06:15")) .addMovement( MELBOURNE, toDate("2008-10-06", "11:00"), toDate("2008-10-12", "11:30")) .addMovement(NEWYORK, toDate("2008-10-14", "12:00"), toDate("2008-10-23", "23:10")) .build(); /* * Voyage number 0200T (by train) * <p/> * New York - Chicago - Dallas */ Voyage NEW_YORK_TO_DALLAS = new VoyageRepository.Builder(vbf, uow, "0200T", NEWYORK) .addMovement(CHICAGO, toDate("2008-10-24", "07:00"), toDate("2008-10-24", "17:45")) .addMovement(DALLAS, toDate("2008-10-24", "21:25"), toDate("2008-10-25", "19:30")) .build(); /* * Voyage number 0300A (by airplane) * <p/> * Dallas - Hamburg - Stockholm - Helsinki */ Voyage DALLAS_TO_HELSINKI = new VoyageRepository.Builder(vbf, uow, "0300A", DALLAS) .addMovement(HAMBURG, toDate("2008-10-29", "03:30"), toDate("2008-10-31", "14:00")) .addMovement( STOCKHOLM, toDate("2008-11-01", "15:20"), toDate("2008-11-01", "18:40")) .addMovement(HELSINKI, toDate("2008-11-02", "09:00"), toDate("2008-11-02", "11:15")) .build(); /* * Voyage number 0301S (by ship) * <p/> * Dallas - Hamburg - Stockholm - Helsinki, alternate route */ Voyage DALLAS_TO_HELSINKI_ALT = new VoyageRepository.Builder(vbf, uow, "0301S", DALLAS) .addMovement(HELSINKI, toDate("2008-10-29", "03:30"), toDate("2008-11-05", "15:45")) .build(); /* * Voyage number 0400S (by ship) * <p/> * Helsinki - Rotterdam - Shanghai - Hongkong */ Voyage HELSINKI_TO_HONGKONG = new VoyageRepository.Builder(vbf, uow, "0400S", HELSINKI) .addMovement( ROTTERDAM, toDate("2008-11-04", "05:50"), toDate("2008-11-06", "14:10")) .addMovement(SHANGHAI, toDate("2008-11-10", "21:45"), toDate("2008-11-22", "16:40")) .addMovement(HONGKONG, toDate("2008-11-24", "07:00"), toDate("2008-11-28", "13:37")) .build(); uow.complete(); } catch (RuntimeException e) { uow.discard(); throw e; } }
public void receivedEmail(ApplicationEvent event, EmailValue email) { UnitOfWork uow = module .unitOfWorkFactory() .newUnitOfWork(UsecaseBuilder.newUsecase("Receive email in conversation")); try { String references = email.headers().get().get("References"); if (hasStreamflowReference(references)) { // This is a response - handle it! List<String> refs = (List<String>) Iterables.addAll( (Collection<String>) new ArrayList<String>(), Iterables.iterable(references.split("[ \r\n\t]"))); // Hotmail handles refs a bit differently... String hotmailRefs = Iterables.first( Iterables.filter( new Specification<String>() { public boolean satisfiedBy(String item) { return item.contains(",") && item.endsWith("@Streamflow>"); } }, refs)); String lastRef = null; if (!Strings.empty(hotmailRefs)) { lastRef = hotmailRefs.split(",")[1]; } else { Collections.reverse(refs); Iterable<String> filter = Iterables.filter( new Specification<String>() { public boolean satisfiedBy(String item) { return item.endsWith("@Streamflow>"); } }, refs); lastRef = Iterables.first(filter); } if (lastRef == null) { ValueBuilder<EmailValue> builder = module .valueBuilderFactory() .newValueBuilder(EmailValue.class) .withPrototype(email); String subj = "Msg Ref missing: " + builder.prototype().subject().get(); builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); logger.error("Could not find message reference in email header:" + lastRef); uow.discard(); return; } Matcher matcher = Pattern.compile("<([^/]*)/([^@]*)@[^>]*>").matcher(lastRef); if (matcher.find()) { String conversationId = matcher.group(1); String participantId = URLDecoder.decode(matcher.group(2), "UTF-8"); if (!"".equals(conversationId) && !"".equals(participantId)) { ConversationParticipant from = uow.get(ConversationParticipant.class, participantId); Conversation conversation = uow.get(Conversation.class, conversationId); CaseEntity caze = (CaseEntity) conversation.conversationOwner().get(); String content = email.content().get(); // If we have an assignee, ensure it is a member of the conversation first if (caze.isAssigned()) { if (!conversation.isParticipant( (ConversationParticipant) caze.assignedTo().get())) conversation.addParticipant((ConversationParticipant) caze.assignedTo().get()); } // Create a new role map and fill it with relevant objects if (RoleMap.current() == null) RoleMap.newCurrentRoleMap(); RoleMap.current().set(from, ConversationParticipant.class); RoleMap.current().set(caze, CaseLoggable.Data.class); RoleMap.current().set(caze, Case.class); Message message = null; if (Translator.HTML.equalsIgnoreCase(email.contentType().get())) { message = conversation.createMessage(email.contentHtml().get(), MessageType.HTML, from); } else { message = conversation.createMessage(email.content().get(), MessageType.PLAIN, from); } // Create attachments for (AttachedFileValue attachedFileValue : email.attachments().get()) { if (!(attachedFileValue.mimeType().get().contains("text/x-vcard") || attachedFileValue.mimeType().get().contains("text/directory"))) { Attachment attachment = message.createAttachment(attachedFileValue.uri().get()); attachment.changeDescription("New Attachment"); attachment.changeName(attachedFileValue.name().get()); attachment.changeMimeType(attachedFileValue.mimeType().get()); attachment.changeModificationDate(attachedFileValue.modificationDate().get()); attachment.changeSize(attachedFileValue.size().get()); attachment.changeUri(attachedFileValue.uri().get()); } } try { if (caze.isStatus(CaseStates.CLOSED)) { RoleMap.newCurrentRoleMap(); RoleMap.current().set(caze); if (caze.assignedTo().get() != null) { RoleMap.current().set(caze.assignedTo().get()); } else { RoleMap.current() .set(uow.get(UserEntity.class, UserEntity.ADMINISTRATOR_USERNAME)); } CaseCommandsContext caseCommands = module.transientBuilderFactory().newTransient(CaseCommandsContext.class); caseCommands.reopen(); caseCommands.unassign(); RoleMap.clearCurrentRoleMap(); } } catch (Throwable e) { ValueBuilder<EmailValue> builder = module .valueBuilderFactory() .newValueBuilder(EmailValue.class) .withPrototype(email); String subj = "Create Case failed: " + builder.prototype().subject().get(); builder .prototype() .subject() .set(subj.length() > 50 ? subj.substring(0, 50) : subj); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); // throw new IllegalStateException("Could not open case through new message.", e); } } } } uow.complete(); } catch (Exception ex) { ValueBuilder<EmailValue> builder = module.valueBuilderFactory().newValueBuilder(EmailValue.class).withPrototype(email); String subj = "Conversation Response Error: " + builder.prototype().subject().get(); builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj); StringBuilder content = new StringBuilder(); content.append("Error Message: " + ex.getMessage()); content.append("\n\rStackTrace:\n\r"); for (StackTraceElement trace : Arrays.asList(ex.getStackTrace())) { content.append(trace.toString() + "\n\r"); } builder.prototype().content().set(content.toString()); // since we create the content of the message our self it's ok to set content type always // to text/plain builder.prototype().contentType().set("text/plain"); // Make sure to address has some value before vi create a case!! if (builder.prototype().to().get() == null) { builder.prototype().to().set("n/a"); } systemDefaults.createCaseOnEmailFailure(builder.newInstance()); uow.discard(); // throw new ApplicationEventReplayException(event, ex); } }