Logback - Programatically added SMTPAppender leaves message body blank - logback

What am I missing? I have the below code which successfully sends an email, but the body of the email is empty. I'd think it has to do with the patternLayout, but everything looks okay. Any ideas on what is going on?
private void createAdminNotifyAppender(LoggerContext lc, AppConfigPropertiesReader propReader)
{
logger.info("Setting up logback admin_notify logging");
//Set up the admin notify appender programatically (needs to use the properties from the propReader above)
OnMarkerEvaluator markerEvaluator = new OnMarkerEvaluator();
markerEvaluator.addMarker(LogbackMarker.ADMIN_NOTIFY.toString());
String adminEmails = propReader.getProperty("adminEmail");
PatternLayout patternLayout = new PatternLayout();
patternLayout.setPattern("[\\(%-6threadHash\\) app=iv %d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level %-25logger{25} - %msg%n");
SMTPAppender adminNotifyAppender = new SMTPAppender();
adminNotifyAppender.setContext(lc);
adminNotifyAppender.setEvaluator(markerEvaluator);
adminNotifyAppender.setSMTPHost(propReader.getProperty("smtpHost"));
for (String adminEmail : adminEmails.split(",")) { adminNotifyAppender.addTo(adminEmail); };
adminNotifyAppender.setFrom(propReader.getProperty("sysEmailAddressNoReply"));
adminNotifyAppender.setSubject("System Alert! [" + propReader.getProperty("environment") + "]");
adminNotifyAppender.setLayout(patternLayout);
adminNotifyAppender.start();
Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.addAppender(adminNotifyAppender);
}

The issue is that both the PatternLayout and the OnMarkerEvaluator have the start methods that should be called (MarkerEvaluator seemed to work without it).
Additionally, both need to know the loggerContext as well (set by calling patternLayout.setContext(lc)), otherwise you'll get out put like the following:
[(%PARSER_ERROR[threadHash]) app=iv %PARSER_ERROR[d]] %PARSER_ERROR[level] %PARSER_ERROR[logger] - %PARSER_ERROR[msg]%PARSER_ERROR[n]
All is well now.

Related

Labels for tooltips on primefaces barchartseries

I have tried to search both the forum and Google extensively, but I have problems understanding how I should make this work:
PrimeFaces6
I have a BarchartModel based on the tutorial in the ShowCase:
CODE: SELECT ALL
private BarChartModel initStatusBarChart() {
BarChartModel model = new BarChartModel();
ChartSeries statusMessages = new ChartSeries();
statusMessages.setLabel("Label"));
statusMessages.set("Some String 1", list1.size());
statusMessages.set("Some String 2", list2.size());
model.addSeries(statusMessages);
return model;
}
The issue is that on render, I get tooltips the format of
"1, 515" and "2, 432", where 515 and 432 are the sizes of list1 and list2, respectively.
How can I replace 1 and 2 with the values "Some String" 1 and 2 ? Have tried extending highlighter and using dataTipFormat, with no success.
I solved the problem using the datatip editor of the chart model (with Primefaces 6.1, by the way). I used this for a stacked bar chart.
I needed to apply this solution at two places: the backing bean and the JSF page.
In the backing bean I had to set a JavaScript function name this way:
barModel.setDatatipEditor("chartDatatipEditor");
I tried to set it using the corresponding tag attribute in the JSF page but to no effect.
In the JSF I inserted this JavaScript code:
<script type="text/javascript">
function chartDatatipEditor(str, seriesIndex, pointIndex, plot) {
//console.log('chartDatatipEditor: '+str+" - "+seriesIndex+" - "+pointIndex);
var point = seriesIndex+','+pointIndex;
#{bean.datatipsJs}
}
</script>
This JS function gets the chart coordinates as parameters. I concat them so that the following JS code gets easier.
seriesIndex is the index of the chart series. pointIndex is the index on the X scale of the diagram.
To find out what are the correct values for your chart you can uncomment the console.log line above.
The inserted JS code is constructed in the backing bean this way:
private Map<String, String> chartDatatips;
public String getDatatipsJs() {
StringBuilder sb = new StringBuilder("switch ( point ) {\n");
for (String point : chartDatatips.keySet()) {
sb.append("case '").append(point).append("': return '").append(chartDatatips.get(point)).append("'; break;\n");
}
sb.append("default: return 'Unknown point'; break; }");
return sb.toString();
}
The map chartDatatips has the coordinate point as key (e.g., "2,1") and the tooltip as value.
During the chart setup you obviously have to fill this map with useful details ;-)
Like this:
chartDatatips.put("2,5", "Label ...");
...
Hope this helps, if you didn't already solved this.
~Alex
Based on Alex's answer I have come up with this. Only requiring javascript - it displays the label and value:
In the backing bean, set a JavaScript function name this way:
barModel.setDatatipEditor("chartDatatipEditor");
In the HTML file:
function chartDatatipEditor(str, seriesIndex, pointIndex, plot) {
return plot.series[seriesIndex].label + ' - ' + plot.data[seriesIndex][pointIndex];
}

convert html to word not working as example

I am trying to convert html to word. I have found so many codes over the net but none of them works. They are worked with string builder or some with others. I have given a code. In debugger it goes through all the codes without error but no file is getting downloaded.
public void converToWord(string htmlContent,string name)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/msword";
string strFileName = name + ".doc";
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline;filename=" + strFileName);
StringBuilder strHTMLContent = new StringBuilder();
strHTMLContent.Append("<html xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:word\" xmlns=\"http://www.w3.org/TR/REC-html40\"><head></head><body>");
strHTMLContent.Append(htmlContent);
strHTMLContent.Append("</body></html>");
HttpContext.Current.Response.Write(strHTMLContent);
HttpContext.Current.Response.End();
HttpContext.Current.Response.Flush();
}
i got an error it says {Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
while the button is in update panel and it does not work properly.everything seems fine but it does not get downloaded.it is a very common problem that happens.just put o a trigger to the button that is firing the event and it will start to work just very much fine.

OWA Signature Update with Exchange Web Services

We're using Exchange Web Services to set user signature in Outlook Web Access. It works great, we see the signature under Options>Settings and the "Automatically include my signature on messages I send" check box is checked. We also set this programmatically.
However, when the user creates a new e-mail message in OWA the signature does not show up. A work around for this is to go to Options>Setting, uncheck the "Automatically include my signature on messages I send" check box , Save, check the check box again and save.
The code we use to set the signature looks something like this:
Folder rootFolder;
UserConfiguration OWAConfig;
rootFolder = Folder.Bind(service, WellKnownFolderName.Root);
OWAConfig = UserConfiguration.Bind(service, "OWA.UserOptions",rootFolder.ParentFolderId, UserConfigurationProperties.All);
OWAConfig.Dictionary["signaturehtml"] = "Hello World";
OWAConfig.Dictionary["autoaddsignature"] = "True";
OWAConfig.Update();
Any idea how to get around this problem?
I have some old code that does the same thing which is working fine. I have pasted the code below. There are a few minor differences between my code and yours. I am not sure if they make a difference but you may want to try it out. Here is an extract of my code with the differences highlighted with a comment:
private void SetSettingValue(UserConfiguration owaConfig, string propName, object propValue)
{
if (owaConfig.Dictionary.ContainsKey(propName))
{
owaConfig.Dictionary[propName] = propValue;
}
else
{
// Adds a key if it does not explicitly exist.
// I am not sure if it makes a difference.
owaConfig.Dictionary.Add(propName, propValue);
}
}
public void AddSignature()
{
// Extract
UserConfiguration OWAConfig = UserConfiguration.Bind(
service,
"OWA.UserOptions",
WellKnownFolderName.Root, // Binding to Root and not Root.ParentFolderId.
UserConfigurationProperties.Dictionary // Binds to Dictionary and not to All.
);
SetSettingValue(OWAConfig, "autoaddsignature", true);
SetSettingValue(OWAConfig, "signaturehtml", html);
OWAConfig.Update();
}

The image I add to a header doesn't appear

I'm trying to create a header with an image; the header is added, but the image is missing in header. My application is deployed on an Oracle Weblogic server (using Java EE and Hibernate).
I'm trying to create the image like this. getImage(seasonalFilter.getPictureFileId()).getAbsolutePath(). The image path is something like this: /tmp/6461346546165461313_65464.jpg.
Note that I want to add text under the image in the header (for every page).
public File convertHtmlToPdf(String JSONString, ExportQueryTypeDTO queryType, String htmlText, ExportTypeDTO type) throws VedStatException {
try {
File retFile = null;
FilterDTO filter = null;
HashMap<Object, Object> properties = new HashMap<Object, Object>(queryType.getHashMap());
filter = JSONCoder.decodeSeasonalFilterDTO(JSONString);
DateFormat formatter = new SimpleDateFormat("yyyy_MM_dd__HH_mm");
//logger.debug("<<<<<< HTML TEXT: " + htmlText + " >>>>>>>>>>>>>>>>");
StringBuilder tmpFileName = new StringBuilder();
tmpFileName.append(formatter.format(new Date()));
retFile = File.createTempFile(tmpFileName.toString(), type.getSuffix());
OutputStream out = new FileOutputStream(retFile);
com.lowagie.text.Document document = new com.lowagie.text.Document(com.lowagie.text.PageSize.LETTER);
com.lowagie.text.pdf.PdfWriter pdfWriter = com.lowagie.text.pdf.PdfWriter.getInstance(document, out);
document.open();
com.lowagie.text.html.simpleparser.HTMLWorker htmlWorker = new com.lowagie.text.html.simpleparser.HTMLWorker(document);
String str = htmlText.replaceAll("ű", "û").replaceAll("ő", "õ").replaceAll("Ő", "Õ").replaceAll("Ű", "Û");
htmlWorker.parse(new StringReader(str));
if (filter instanceof SeasonalFilterDTO) {
SeasonalFilterDTO seasonalFilter = (SeasonalFilterDTO) filter;
if (seasonalFilter.getPictureFileId() != null) {
logger.debug("Image absolutePath: " + getImage(seasonalFilter.getPictureFileId()).getAbsolutePath());
Image logo = Image.getInstance(getImage(seasonalFilter.getPictureFileId()).getAbsolutePath());
logo.setAlignment(Image.MIDDLE);
logo.setAbsolutePosition(0, 0);
logo.scalePercent(100);
Chunk chunk = new Chunk(logo, 0, 0);
HeaderFooter header = new HeaderFooter(new Phrase(chunk), true);
header.setBorder(Rectangle.NO_BORDER);
document.setHeader(header);
}
}
document.close();
return retFile;
} catch (Exception e) {
throw new VedStatException(e);
}
}
I really dislike your false allegation that "Every tutorial is based on C:\imagelocation\dsadsa.jpg"
I'm the author of two books and many tutorials about iText and I know for a fact that what you say doesn't make any sense. Take a look at my name: "Bruno Lowagie." You are using my name in your code, so please believe me when I say you're doing it completely wrong.
Instead of HTMLWorker, you should use XML Worker. HTMLWorker is no longer supported and will probably be removed from iText in the near future.
I see that you're also using the HeaderFooter class. This class has been removed several years ago. Please take a look at the newer examples: http://www.itextpdf.com/themes/keyword.php?id=221
These examples are written in Java; if you need the C# version, please look for the corresponding C# examples in the SVN repository.
Regarding images, you may want to read chapter 10 of my book.
Finally: please read http://lowagie.com/itext2

call code behind functions with html controls

I have a simple function that I want to call in the code behind file name Move
and I was trying to see how this can be done and Im not using asp image button because not trying to use asp server side controls since they tend not to work well with ASP.net MVC..the way it is set up now it will look for a javascript function named Move but I want it to call a function named move in code behind of the same view
<img alt='move' id="Move" src="/Content/img/hPrevious.png" onclick="Move()"/>
protected void Move(){
}
//based on Search criteria update a new table
protected void Search(object sender EventArgs e)
{
for (int i = 0; i < data.Count; i++){
HtmlTableRow row = new HtmlTableRow();
HtmlTableCell CheckCell = new HtmlTableCell();
HtmlTableCell firstCell = new HtmlTableCell();
HtmlTableCell SecondCell = new HtmlTableCell();
CheckBox Check = new CheckBox();
Check.ID = data[i].ID;
CheckCell.Controls.Add(Check);
lbl1.Text = data[i].Date;
lbl2.Text = data[i].Name;
row.Cells.Add(CheckCell);
row.Cells.Add(firstCell);
row.Cells.Add(SecondCell);
Table.Rows.Add(row);
}
}
Scott Guthrie has a very good example on how to do this using routing rules.
This would give you the ability to have the user navigate to a URL in the format /Search/[Query]/[PageNumber] like http://site/Search/Hippopotamus/3 and it would show page 3 of the search results for hippopotamus.
Then in your view just make the next button point to "http://site/Search/Hippopotamus/4", no javascript required.
Of course if you wanted to use javascript you could do something like this:
function Move() {
var href = 'http://blah/Search/Hippopotamus/2';
var slashPos = href.lastIndexOf('/');
var page = parseInt(href.substring(slashPos + 1, href.length));
href = href.substring(0, slashPos + 1);
window.location = href + (++page);
}
But that is much more convoluted than just incrementing the page number parameter in the controller and setting the URL of the next button.
You cannot do postbacks or call anything in a view from JavaScript in an ASP.NET MVC application. Anything you want to call from JavaScript must be an action on a controller. It's hard to say more without having more details about what you're trying to do, but if you want to call some method "Move" in your web application from JavaScript, then "Move" must be an action on a controller.
Based on comments, I'm going to update this answer with a more complete description of how you might implement what I understand as the problem described in the question. However, there's quite a bit of information missing from the question so I'm speculating here. Hopefully, the general idea will get through, even if some of the details do not match TStamper's exact code.
Let's start with a Controller action:
public ActionResult ShowMyPage();
{
return View();
}
Now I know that I want to re-display this page, and do so using an argument passed from a JavaScript function in the page. Since I'll be displaying the same page again, I'll just alter the action to take an argument. String arguments are nullable, so I can continue to do the initial display of the page as I always have, without having to worry about specifying some kind of default value for the argument. Here's the new version:
public ActionResult ShowMyPage(string searchQuery);
{
ViewData["SearchQuery"] = searchQuery;
return View();
}
Now I need to call this page again in JavaScript. So I use the same URL I used to display the page initially, but I append a query string parameter with the table name:
http://example.com/MyControllerName/ShowMyPage?searchQuery=tableName
Finally, in my aspx I can call a code behind function, passing the searchQuery from the view data. Once again, I have strong reservations about using code behind in an MVC application, but this will work.
How to call a code-behind function in aspx:
<% Search(ViewData["searchQuery"]); %>
I've changed the arguments. Since you're not handling an event (with a few exceptions, such as Page_Load, there aren't any in MVC), the Search function doesn't need the signature of an event handler. But I did add the "tablename" argument so that you can pass that from the aspx.
Once more, I'll express my reservations about doing this in code behind. It strikes me that you are trying to use standard ASP.NET techniques inside of the MVC framework, when MVC works differently. I'd strongly suggest going through the MVC tutorials to see examples of more standard ways of doing this sort of thing.