1 56 package org.opencrx.kernel.workflow.servlet; 57 58 import java.io.IOException ; 59 import java.io.PrintWriter ; 60 import java.net.HttpURLConnection ; 61 import java.net.MalformedURLException ; 62 import java.net.URL ; 63 import java.net.URLDecoder ; 64 import java.util.ArrayList ; 65 import java.util.Arrays ; 66 import java.util.Date ; 67 import java.util.HashSet ; 68 import java.util.Iterator ; 69 import java.util.List ; 70 import java.util.Set ; 71 72 import javax.naming.Context ; 73 import javax.naming.InitialContext ; 74 import javax.naming.NamingException ; 75 import javax.servlet.ServletConfig ; 76 import javax.servlet.ServletException ; 77 import javax.servlet.http.HttpServlet ; 78 import javax.servlet.http.HttpServletRequest ; 79 import javax.servlet.http.HttpServletResponse ; 80 81 import org.opencrx.kernel.generic.SecurityKeys; 82 import org.opencrx.kernel.workflow1.cci.WfProcess; 83 import org.openmdx.base.accessor.generic.view.Manager_1; 84 import org.openmdx.base.accessor.jmi.cci.JmiServiceException; 85 import org.openmdx.base.accessor.jmi.cci.RefPackage_1_0; 86 import org.openmdx.base.accessor.jmi.spi.RefRootPackage_1; 87 import org.openmdx.base.exception.ServiceException; 88 import org.openmdx.compatibility.application.dataprovider.transport.ejb.cci.Dataprovider_1ConnectionFactoryImpl; 89 import org.openmdx.compatibility.base.dataprovider.cci.QualityOfService; 90 import org.openmdx.compatibility.base.dataprovider.cci.RequestCollection; 91 import org.openmdx.compatibility.base.dataprovider.cci.ServiceHeader; 92 import org.openmdx.compatibility.base.dataprovider.transport.adapter.Provider_1; 93 import org.openmdx.compatibility.base.dataprovider.transport.cci.Dataprovider_1_1Connection; 94 import org.openmdx.compatibility.base.dataprovider.transport.cci.Provider_1_0; 95 import org.openmdx.compatibility.base.dataprovider.transport.delegation.Connection_1; 96 import org.openmdx.compatibility.base.naming.Path; 97 import org.openmdx.kernel.exception.BasicException; 98 import org.openmdx.model1.accessor.basic.spi.Model_1; 99 import org.openmdx.uses.java.net.URLEncoder; 100 101 107 public class WorkflowControllerServlet 108 extends HttpServlet { 109 110 public class WorkflowMonitor 111 implements Runnable { 112 113 public WorkflowMonitor( 114 long pingRate, 115 List monitoredURLs 116 ) { 117 this.pingRate = pingRate; 118 this.monitoredURLs = monitoredURLs; 119 } 120 121 public void run( 122 ) { 123 while(true) { 124 try { 125 for( 126 Iterator i = this.monitoredURLs.iterator(); 127 i.hasNext(); 128 ) { 129 URL url = (URL )i.next(); 130 try { 131 HttpURLConnection connection = (HttpURLConnection )url.openConnection(); 132 connection.setInstanceFollowRedirects(false); 133 connection.setDoInput(true); 134 connection.setDoOutput(true); 135 connection.setRequestMethod("POST"); 136 int rc = connection.getResponseCode(); 137 if(rc != HttpURLConnection.HTTP_OK) { 138 System.out.println(new Date ().toString() + ": openCRX/WorkflowController: response code for " + url + " " + rc); 139 } 140 } 141 catch(IOException e) { 142 new ServiceException(e).log(); 143 } 144 } 145 try { 146 Thread.sleep(this.pingRate * 60000L); 147 } 148 catch (InterruptedException e) {} 149 } 150 catch(Exception e) {} 151 } 152 } 153 154 private final List monitoredURLs; 155 private final long pingRate; 156 157 } 158 159 private RefPackage_1_0 createDataPkg( 161 ServiceHeader header 162 ) throws ServiceException { 163 Provider_1_0 provider = new Provider_1( 164 new RequestCollection( 165 header, 166 this.connectionData 167 ), 168 false 169 ); 170 Manager_1 manager = new Manager_1( 171 new Connection_1( 172 provider, 173 false 174 ) 175 ); 176 RefPackage_1_0 rootPkg = new RefRootPackage_1(manager); 177 return rootPkg; 178 } 179 180 public void init( 182 ServletConfig config 183 ) throws ServletException { 184 185 super.init(config); 186 187 int ii = 0; 189 List modelPackages = new ArrayList (); 190 while(getInitParameter("modelPackage[" + ii + "]") != null) { 191 modelPackages.add( 192 getInitParameter("modelPackage[" + ii + "]") 193 ); 194 ii++; 195 } 196 try { 197 new Model_1().addModels(modelPackages); 198 } 199 catch(Exception e) { 200 System.out.println("can not initialize model repository " + e.getMessage()); 201 System.out.println(new ServiceException(e).getCause()); 202 } 203 204 Context initialContext; 205 try { 206 initialContext = new InitialContext (); 207 } catch (NamingException e) { 208 throw new ServletException ("can not get the initial context", e); 209 } 210 211 Set segmentNames = new HashSet (); 213 try { 214 this.connectionData = Dataprovider_1ConnectionFactoryImpl.createGenericConnection( 215 initialContext.lookup("java:comp/env/ejb/data") 216 ); 217 RefPackage_1_0 dataPkg = this.createDataPkg( 218 new ServiceHeader(SecurityKeys.ROOT_PRINCIPAL, null, false, new QualityOfService()) 219 ); 220 Set excludeRealms = new HashSet (); 221 for(ii = 0; ii < 100; ii++) { 222 if(this.getInitParameter("excludeRealm[" + ii + "]") != null) { 223 excludeRealms.add( 224 this.getInitParameter("excludeRealm[" + ii + "]") 225 ); 226 } 227 } 228 org.openmdx.security.realm1.cci.Segment realmSegment = 229 (org.openmdx.security.realm1.cci.Segment)dataPkg.refObject( 230 this.getInitParameter("realmSegment") 231 ); 232 for(Iterator i = realmSegment.getRealm().iterator(); i.hasNext(); ) { 233 org.openmdx.security.realm1.cci.Realm realm = (org.openmdx.security.realm1.cci.Realm)i.next(); 234 if(!excludeRealms.contains(realm.getName())) { 235 segmentNames.add(realm.getName()); 236 } 237 } 238 } 239 catch(Exception e) { 240 throw new ServletException ("Error occured while retrieving realms", e); 241 } 242 243 this.configuredPaths = new ArrayList (); 245 String providerName = new Path(this.getInitParameter("realmSegment")).get(2); 246 for(Iterator j = segmentNames.iterator(); j.hasNext(); ) { 247 String segmentName = (String )j.next(); 248 ii = 0; 249 while(this.getInitParameter("path[" + ii + "]") != null) { 250 this.configuredPaths.add( 251 this.getInitParameter("path[" + ii + "]") + "/execute?provider=" + providerName + "&segment=" + segmentName 252 ); 253 ii++; 254 } 255 } 256 this.monitoredURLs = new ArrayList (); 257 } 258 259 263 protected static org.opencrx.kernel.workflow1.cci.workflow1Package getWorkflowPkg( 264 RefPackage_1_0 rootPkg 265 ) { 266 return (org.opencrx.kernel.workflow1.cci.workflow1Package)rootPkg.refPackage( 267 org.opencrx.kernel.workflow1.cci.workflow1Package.class.getName() 268 ); 269 } 270 271 275 protected static org.opencrx.kernel.workflow1.cci.Segment getWorkflowSegment( 276 RefPackage_1_0 rootPkg, 277 String providerName, 278 String segmentName 279 ) { 280 return (org.opencrx.kernel.workflow1.cci.Segment) rootPkg.refObject( 281 "xri:@openmdx:org.opencrx.kernel.workflow1/provider/" 282 + providerName + "/segment/" + segmentName 283 ); 284 } 285 286 protected static org.opencrx.kernel.workflow1.cci.Topic initTopic( 288 RefPackage_1_0 rootPkg, 289 org.opencrx.kernel.workflow1.cci.workflow1Package workflowPkg, 290 org.opencrx.kernel.workflow1.cci.Segment workflowSegment, 291 String id, 292 String name, 293 String description, 294 String topicPathPattern, 295 WfProcess[] actions 296 ) { 297 org.opencrx.kernel.workflow1.cci.Topic topic = null; 298 try { 299 topic = workflowSegment.getTopic(id); 300 } 301 catch(JmiServiceException e) { 302 if(e.getExceptionCode() != BasicException.Code.NOT_FOUND) { 303 throw e; 304 } 305 rootPkg.refBegin(); 306 topic = workflowPkg.getTopicClass().createTopic(); 307 topic.setName(name); 308 topic.setDescription(description); 309 topic.setTopicPathPattern(topicPathPattern); 310 topic.getPerformAction().addAll( 311 Arrays.asList(actions) 312 ); 313 topic.getOwningGroup().addAll( 314 workflowSegment.getOwningGroup() 315 ); 316 workflowSegment.addTopic( 317 id, 318 topic 319 ); 320 rootPkg.refCommit(); 321 } 322 return topic; 323 } 324 325 protected static org.opencrx.kernel.workflow1.cci.WfProcess initWorkflow( 327 RefPackage_1_0 rootPkg, 328 org.opencrx.kernel.workflow1.cci.workflow1Package workflowPkg, 329 org.opencrx.kernel.workflow1.cci.Segment workflowSegment, 330 String id, 331 String name, 332 String description, 333 Boolean isSynchronous 334 ) { 335 org.opencrx.kernel.workflow1.cci.WfProcess process = null; 336 try { 337 process = (org.opencrx.kernel.workflow1.cci.WfProcess)workflowSegment.getWfProcess(id); 338 } 339 catch(JmiServiceException e) { 340 if(e.getExceptionCode() != BasicException.Code.NOT_FOUND) { 341 throw e; 342 } 343 rootPkg.refBegin(); 344 process = workflowPkg.getWfProcessClass().createWfProcess(); 345 process.setName(name); 346 process.setDescription(description); 347 process.setSynchronous(isSynchronous); 348 process.setPriority((short)0); 349 process.getOwningGroup().addAll( 350 workflowSegment.getOwningGroup() 351 ); 352 workflowSegment.addWfProcess( 353 id, 354 process 355 ); 356 rootPkg.refCommit(); 357 } 358 return process; 359 } 360 361 public static void initWorkflows( 363 RefPackage_1_0 rootPkg, 364 String providerName, 365 String segmentName 366 ) throws ServiceException { 367 org.opencrx.kernel.workflow1.cci.workflow1Package workflowPkg = getWorkflowPkg( 368 rootPkg 369 ); 370 org.opencrx.kernel.workflow1.cci.Segment workflowSegment = getWorkflowSegment( 371 rootPkg, 372 providerName, 373 segmentName 374 ); 375 initWorkflow( 377 rootPkg, 378 workflowPkg, 379 workflowSegment, 380 WORKFLOW_EXPORT_MAIL, 381 org.opencrx.mail.workflow.ExportMailWorkflow.class.getName(), 382 "Export mails", 383 Boolean.FALSE 384 ); 385 initWorkflow( 387 rootPkg, 388 workflowPkg, 389 workflowSegment, 390 WORKFLOW_SEND_MAIL, 391 org.opencrx.mail.workflow.SendMailWorkflow.class.getName(), 392 "Send mails", 393 Boolean.FALSE 394 ); 395 WfProcess sendMailNotificationWorkflow = initWorkflow( 397 rootPkg, 398 workflowPkg, 399 workflowSegment, 400 WORKFLOW_SEND_MAIL_NOTIFICATION, 401 org.opencrx.mail.workflow.SendMailNotificationWorkflow.class.getName(), 402 "Send mail notifications", 403 Boolean.FALSE 404 ); 405 WfProcess sendAlertWorkflow = initWorkflow( 407 rootPkg, 408 workflowPkg, 409 workflowSegment, 410 WORKFLOW_SEND_ALERT, 411 org.opencrx.kernel.workflow.SendAlert.class.getName(), 412 "Send alert", 413 Boolean.TRUE 414 ); 415 initWorkflow( 417 rootPkg, 418 workflowPkg, 419 workflowSegment, 420 WORKFLOW_PRINT_CONSOLE, 421 org.opencrx.kernel.workflow.PrintConsole.class.getName(), 422 "Print to console", 423 Boolean.TRUE 424 ); 425 WfProcess[] actions = new WfProcess[]{ 426 sendAlertWorkflow, 427 sendMailNotificationWorkflow 428 }; 429 initTopic( 430 rootPkg, 431 workflowPkg, 432 workflowSegment, 433 "AccountModifications", 434 "Account Modifications", 435 "Send alert for modified accounts", 436 "xri:@openmdx:org.opencrx.kernel.account1/provider/:*/segment/:*/account/:*", 437 actions 438 ); 439 initTopic( 440 rootPkg, 441 workflowPkg, 442 workflowSegment, 443 "ActivityFollowUpModifications", 444 "Activity Follow Up Modifications", 445 "Send alert for modified activity follow ups", 446 "xri:@openmdx:org.opencrx.kernel.activity1/provider/:*/segment/:*/activity/:*/followUp/:*", 447 actions 448 ); 449 initTopic( 450 rootPkg, 451 workflowPkg, 452 workflowSegment, 453 "ActivityModifications", 454 "Activity Modifications", 455 "Send alert for modified activities", 456 "xri:@openmdx:org.opencrx.kernel.activity1/provider/:*/segment/:*/activity/:*", 457 actions 458 ); 459 initTopic( 460 rootPkg, 461 workflowPkg, 462 workflowSegment, 463 "BookingModifications", 464 "Booking Modifications", 465 "Send alert for modified bookings", 466 "xri:@openmdx:org.opencrx.kernel.depot1/provider/:*/segment/:*/booking/:*", 467 actions 468 ); 469 initTopic( 470 rootPkg, 471 workflowPkg, 472 workflowSegment, 473 "Competitor Modifications", 474 "Competitor Modifications", 475 "Send alert for modified competitors", 476 "xri:@openmdx:org.opencrx.kernel.account1/provider/:*/segment/:*/competitor/:*", 477 actions 478 ); 479 initTopic( 480 rootPkg, 481 workflowPkg, 482 workflowSegment, 483 "CompoundBookingModifications", 484 "Compound Booking Modifications", 485 "Send alert for modified compound bookings", 486 "xri:@openmdx:org.opencrx.kernel.depot1/provider/:*/segment/:*/cb/:*", 487 actions 488 ); 489 initTopic( 490 rootPkg, 491 workflowPkg, 492 workflowSegment, 493 "InvoiceModifications", 494 "Invoice Modifications", 495 "Send alert for modified invoices", 496 "xri:@openmdx:org.opencrx.kernel.contract1/provider/:*/segment/:*/invoice/:*", 497 actions 498 ); 499 initTopic( 500 rootPkg, 501 workflowPkg, 502 workflowSegment, 503 "LeadModifications", 504 "Lead Modifications", 505 "Send alert for modified leads", 506 "xri:@openmdx:org.opencrx.kernel.contract1/provider/:*/segment/:*/lead/:*", 507 actions 508 ); 509 initTopic( 510 rootPkg, 511 workflowPkg, 512 workflowSegment, 513 "OpportunityModifications", 514 "Opportunity Modifications", 515 "Send alert for modified opportunities", 516 "xri:@openmdx:org.opencrx.kernel.contract1/provider/:*/segment/:*/opportunity/:*", 517 actions 518 ); 519 initTopic( 520 rootPkg, 521 workflowPkg, 522 workflowSegment, 523 "OrganizationModifications", 524 "Organization Modifications", 525 "Send alert for modified organizations", 526 "xri:@openmdx:org.opencrx.kernel.account1/provider/:*/segment/:*/organization/:*", 527 actions 528 ); 529 initTopic( 530 rootPkg, 531 workflowPkg, 532 workflowSegment, 533 "ProductModifications", 534 "Product Modifications", 535 "Send alert for modified products", 536 "xri:@openmdx:org.opencrx.kernel.product1/provider/:*/segment/:*/product/:*", 537 actions 538 ); 539 initTopic( 540 rootPkg, 541 workflowPkg, 542 workflowSegment, 543 "QuoteModifications", 544 "Quote Modifications", 545 "Send alert for modified quotes", 546 "xri:@openmdx:org.opencrx.kernel.contract1/provider/:*/segment/:*/quote/:*", 547 actions 548 ); 549 initTopic( 550 rootPkg, 551 workflowPkg, 552 workflowSegment, 553 "SalesOrderModifications", 554 "Sales Order Modifications", 555 "Send alert for modified sales orders", 556 "xri:@openmdx:org.opencrx.kernel.contract1/provider/:*/segment/:*/salesOrder/:*", 557 actions 558 ); 559 } 560 561 private URL getMonitoredURL( 563 String path, 564 HttpServletRequest req 565 ) throws MalformedURLException { 566 String requestURL = req.getRequestURL().toString(); 567 return new URL ( 568 requestURL.substring(0, requestURL.indexOf(req.getServletPath())) + path 569 ); 570 } 571 572 protected void handleRequest( 574 HttpServletRequest req, 575 HttpServletResponse res 576 ) throws ServletException , IOException { 577 578 if(this.workflowMonitor == null) { 580 this.workflowMonitor = new Thread ( 581 new WorkflowMonitor( 582 this.pingRate, 583 this.monitoredURLs 584 ) 585 ); 586 this.workflowMonitor.start(); 587 } 588 589 if(COMMAND_START.equals(req.getPathInfo())) { 591 for( 592 Iterator i = this.configuredPaths.iterator(); 593 i.hasNext(); 594 ) { 595 String path = (String )i.next(); 596 if(URLEncoder.encode(path.toString(), "UTF-8").equals(req.getQueryString())) { 597 this.monitoredURLs.add( 598 this.getMonitoredURL(path, req) 599 ); 600 break; 601 } 602 } 603 } 604 else if(COMMAND_STOP.equals(req.getPathInfo())) { 605 URL monitoredURL = this.getMonitoredURL( 606 URLDecoder.decode(req.getQueryString(), "UTF-8"), 607 req 608 ); 609 for( 610 Iterator i = this.monitoredURLs.iterator(); 611 i.hasNext(); 612 ) { 613 URL url = (URL )i.next(); 614 if(url.equals(monitoredURL)) { 615 i.remove(); 616 break; 617 } 618 } 619 } 620 else if(COMMAND_SLOWDOWN_PING_RATE.equals(req.getPathInfo())) { 621 this.pingRate++; 622 } 623 else if(COMMAND_SPEEDUP_PING_RATE.equals(req.getPathInfo())) { 624 if(this.pingRate > 1) { 625 this.pingRate--; 626 } 627 } 628 629 PrintWriter out = res.getWriter(); 631 out.println("<h2>openCRX Workflow Controller</h2>"); 632 out.println("<table>"); 633 for( 634 Iterator i = this.configuredPaths.iterator(); 635 i.hasNext(); 636 ) { 637 String path = (String )i.next(); 638 boolean active = this.monitoredURLs.contains(this.getMonitoredURL(path, req)); 639 out.println("<tr>"); 640 out.println("<td>" + path + "</td><td><a HREF=\"" + req.getContextPath() + req.getServletPath() + (active ? "/stop" : "/start") + "?" + URLEncoder.encode(path.toString(), "UTF-8") + "\">" + (active ? "Turn Off" : "Turn On") + "</a></td>"); 641 out.println("</tr>"); 642 } 643 out.println("</table>"); 644 out.println("<h3>Set ping rate</h3>"); 645 out.println("Current ping rate: 1 ping every " + this.pingRate + " minute(s)"); 646 out.println("<br /><a HREF=\"" + req.getContextPath() + req.getServletPath() + "/speedup\">Speed up ping rate</a>"); 647 out.println("<br /><a HREF=\"" + req.getContextPath() + req.getServletPath() + "/slowdown\">Slow down ping rate</a>"); 648 } 649 650 protected void doGet( 652 HttpServletRequest req, 653 HttpServletResponse res 654 ) throws ServletException , IOException { 655 this.handleRequest( 656 req, 657 res 658 ); 659 } 660 661 protected void doPost( 663 HttpServletRequest req, 664 HttpServletResponse res 665 ) throws ServletException , IOException { 666 this.handleRequest( 667 req, 668 res 669 ); 670 } 671 672 private static final long serialVersionUID = -2397456308895573603L; 676 private static final String COMMAND_START = "/start"; 677 private static final String COMMAND_STOP = "/stop"; 678 private static final String COMMAND_SLOWDOWN_PING_RATE = "/slowdown"; 679 private static final String COMMAND_SPEEDUP_PING_RATE = "/speedup"; 680 681 public static final String WORKFLOW_EXPORT_MAIL = "ExportMail"; 682 public static final String WORKFLOW_SEND_MAIL = "SendMail"; 683 public static final String WORKFLOW_SEND_MAIL_NOTIFICATION = "SendMailNotification"; 684 public static final String WORKFLOW_SEND_ALERT = "SendAlert"; 685 public static final String WORKFLOW_PRINT_CONSOLE = "PrintConsole"; 686 687 private List configuredPaths = null; 688 private List monitoredURLs = null; 689 private Thread workflowMonitor = null; 690 private long pingRate = 1L; private Dataprovider_1_1Connection connectionData = null; 692 693 } 694 695 | Popular Tags |