понедельник, 16 мая 2016 г.

Отключение дампов памяти при ошибке в Upsource и Cassandra

Последнее время Upsource стал занимать неприлично большое кол-во дискового пространства, при 9 подключенных проектах. Быстрый анализ показал наличие дампов памяти в папке \logs\cassandra.

Логи можно безболезненно удалить и внести изменение в конфигурацию (описано ниже), либо настроить регулярное задание по очистке дампов средствами ОС, подход каждый решает сам.

По умолчанию JVM запускается с опцией -XX:+HeapDumpOnOutOfMemoryError, это значит, что при возникновении ошибки OutOfMemory будет сделан дамп памяти и записан по умолчанию в \logs\cassandra в виде файлов формата pidXXXXX_.hprof.

Для отключения этой опции необходимо в файлах launcher.setenv.bat, либо в launcher.setenv.sh (зависит от ОС), убрать удалить опцию -XX:+HeapDumpOnOutOfMemoryError

Файлы расположены по следующим путям:
 \launcher\conf  
 \apps\cassandra\launcher\conf  
 \apps\hub\launcher\conf  
 \apps\upsource-analyzer\launcher\conf  
 \apps\upsource-frontend\launcher\conf  
 \apps\upsource-monitoring\launcher\conf  
 \apps\vcs-settings\launcher\conf  

P.S. Описанный способ только устраняет последствия, настоятельно рекомендую найти причину ошибки и устранить её.

пятница, 29 апреля 2016 г.

Предотвращение множественной отправки формы

При валидации формы на стороне клиента и длительном сабмите формы, пользователь может нажать кнопку несколько раз, чем вызовет несколько последовательных отправок форм. Эта ошибка исправлена в версии 2.0.8 либо смотреть на github.

понедельник, 25 апреля 2016 г.

iOS9 и AppleTV2

Имеем apple tv2, которой был сделан непривязанный джэйлбрэйк и россыпь apple устройств всех мастей. В какой-то момент устройства перестали иметь возможность транслировать видео на приставку, т.е. приставка видна в AirPlay, но есть возможность транслировать только звук. Беглый поиск выявил проблему - Apple усилила безопасность и обновила протоколы обмена данных, а устройства как раз обновились до iOS9 и El Capitan. 

Меню обновления на AppleTV говорит, что установлена последняя версия, а сброс настроек на заводские не работает - всё ясно, проделки джэйлбрэйка, чтобы случайно не обновить приставку. При подключении к iTunes обновить устройство тоже не удаётся. 

Выход - переводим apple tv в DFU режим:
1. Подключаем питание к приставке
2. Подключаем приставку к ноутбуку
3. Открываем iTunes
4. Зажимаем на пульте кнопки "Вниз" и "Меню" на 6 секунд - диод на приставке начнет мигать
5. Зажимаем на пульте кнопки "Меню" и "Воспроизведение/Пауза" на 6 секунд
6. В iTunes появляется возможность восстановления прошивки AppleTV 
7. Загрузка последней версии прошивки и установка её на приставку произойдет автоматически

четверг, 21 апреля 2016 г.

Aspose.PDF обновление полей

Столкнулся с задачей программного заполнения полей в PDF документе. Под рукой был Aspose.PDF, поэтому воспользовался им.

Вся информация по работе есть в официальных гайдах Aspose, но была пара моментов, которые были не описаны.

Допустим у вас есть файл PDF с полями для заполнения, например это 3-НДФЛ с сайта налоговой.

Чтобы заполнить поле, нужно всего лишь знать его имя, а этого у нас нет, восполним пробел и выгрузим название всех полей в файл.

 Aspose.Pdf.Facades.Form form = new Aspose.Pdf.Facades.Form();  
 form.BindPdf("example.pdf");  
 System.IO.FileStream xmlOutputStream = new FileStream("fields.xml", FileMode.Create);  
 form.ExportXml(xmlOutputStream);  
 xmlOutputStream.Close();  
 form.Dispose();  

В результате получили обычный XML, только беда, есть поля, которые содержат вложенные поля, к ним обратиться по имени не получится, например как изменить значение поля Text6->name2?

 <fields>  
  <field name="Text6">  
   <field name="2">  
    <value>760</value>  
   </field>  
  </field>  
 </fields>  

Для этого получим названия всех полей в PDF, для простоты выгрузим в файл fields.txt

 Aspose.Pdf.Facades.Form form = new Aspose.Pdf.Facades.Form();  
 form.BindPdf("example.pdf");  
 string[] fields = form.FieldNames;  
 StreamWriter sw = new StreamWriter("fields.txt");  
       foreach (string field in fields)  
       {  
         sw.WriteLine(field);  
       }  
 sw.Flush();  
 sw.Close();  

В результате видим, что доступ к дереву полей происходит через точку, а значит полное имя поля выглядит следующим образом Text6.2

Остается только поменять значение этого поля согласно инструкции

 //Create Form Object  
 Aspose.Pdf.Facades.Form pdfForm = new Aspose.Pdf.Facades.Form();  
 //Open Document  
 pdfForm.BindPdf("input.pdf");  
 pdfForm.FillField("Text6.2", "Ура, работает!");  
 //save updated file  
 pdfForm.Save("output.pdf");  



суббота, 26 марта 2016 г.

DataGrip - Перенос источников данных на другой компьютер

Несколько месяцев назад мы перешли на использование JetBrains DataGrip в качестве средства работы с базами данных, т.к. она позволяет работать с различными БД в одном приложении.

Источников данных достаточно много и желания настраивать их каждому сотруднику не было, поэтому для распространения настроек воспользовались функцией импорта и экспорта.

Для начала все же необходимо настроить все источники одному сотруднику, по умолчанию они создаются на уровне проекта, чтобы появилась возможность экспорта нужно сделать их глобальными. Для этого в разделе Data sources and drivers нужно выбрать источник и нажать кнопку Make Global, после чего можно экспортировать настройки и передавать коллегам.

пятница, 25 марта 2016 г.

Динамическое создание файлов Excel в пакете MS Integration Services (SSIS)

Задача: В процессе выполнения SSIS пакета формировать файлы Excel с информацией. Например вы выгружаете информацию по продажам и необходимо формировать отдельный файл для каждого филиала.

Считаем, что вы знаете как пользоваться Foreach Loop контейнером, т.к. создание Excel файлов находится внутри него и у вас настроены все источники данных.

1. Добавить Execute SQL Task в контейнер цикла
2. В его свойствах указать ConnectionType = EXCEL
3. Создать новое подключение, раскрыв список в Connection

4. Указать путь к файлу. Важно: можно как выбрать существующий файл, так и указать имя отсутствующего файла, но по существующему пути. В моем случае путь E:\SSIS_Packages\Temp\ реальный, а файл Temp.xls не существует.
5. Указать версию Excel

6. Сохраняем все настройки (элемент будет отображен с ошибкой, пока игнорируем)
7. Добавляем Data Flow Task
8. Соединяем Execute SQL Task с Data Flow Task
9. Внутрь Data Flow Task добавляем ваш источник данных (не забываем, что Excel принимает unicode формат, поэтому необходимо сделать предварительную конвертацию), Excel Destination и соединяем их
10. Создаем переменную sqlCreateExcelSheet, которая будет содержать скрипт создания листа Excel
11. Создаем переменную strExcelListName, которая будет содержать название листа в Excel
12. Открываем свойства Excel Destination, выбираем ранее созданный Connection Manager, способ доступа к данным Table or view и нажимаем кнопку New...
13. В новом окне откроется скрипт создания листа Excel, в нем меняем все varchar и nvarchar на LongText, а также меняем имя листа на свое, например MySheet. Копируем скрипт и сохраняем.

14. В свойстве Name of the Excel sheet выбираем лист со знаком $, который мы только что создали и переходим в раздел Mappings, в котором настраиваем все соответствия источника и приемника. Сохраняем.
15. В переменную strExcelListName сохраняем имя нашего листа без знака $. В нашем случае это MySheet
16. Открываем для переменной sqlCreateExcelSheet окно Expression и вставляем в скрипт, скопированный на шаге 13. Заменяем название листа в тексте скрипта на переменную strExcelListName и сохраняем

17. Возвращаемся в свойства Execute SQL Task. SQLSourceType = Variable, SourceVariable = User::sqlCreateExcelSheet. Сохраняем.


18, В свойствах Exce Connection Manager ставим DelayValidation = true, т.к.файлы будут существовать только на момент выполнения пакета

19. Также у вас должна существовать переменная strFileName, которая содержит имя и путь файла, мы предполагаем, что в каждой итерации цикла в ней будет свое значение (не описано в рамках этой статьи). Открываем раздел Expressions Excel Connection Manager и переопределяем свойство ExcelFilePath на @[User::strFileName]

20. Финальным шагом в свойствах Excel Destination указываем способ получения данных Table name or view name variable и в качестве переменной выбираем strExcelListName

21. Запускаем пакет.






понедельник, 21 марта 2016 г.

Запуск неподписанных скриптов PowerShell

Симптомы:
при запуске скрипта PowerShell возникает ошибка "Не удается загрузить файл ХХХХ, так как выполнение скриптов запрещено для данной системы."

Решение:
Необходимо изменить политику выполнения скриптов. Для этого запустить PowerShell ISE или консоль от имени администратора и выполнить "Set-ExecutionPolicy YYYY", где YYYY

  • Unrestricted - выполнение любых сценариев без подписи
  • RemoteSigned - локальные без подписи, загруженные с сети с подписью
  • AllSigned - все сценарии должны быть подписаны
  • Restricted - (по умолчанию) все сценарии запрещены, только одиночные командами в интерактивном режиме

Для разработки и отладки я выбираю RemoteSigned



пятница, 18 марта 2016 г.

Настройка JetBrains DataGrip для подключения к Sybase ASE (Native vs jTds)

Источник Sybase ASE можно подключить в DataGrip как с использованием драйверов jTds, которые можно загрузить непосредственно из меню настроек источника, так и через родные драйвера Sybase.

Драйвер jConnect устанавливается вместе с Sybase PCClient, и обычно находится в папке C:\Sybase\jConnect-7_0\classes, либо его можно скачать вместе с SDK с сайта http://store.sap.com используя для поиска "SDK for Adaptive Server Enterprise"

Для настройки native драйверов достаточно указать файл как показано на рисунке ниже (клик для увеличения):

Native вариант работает быстрее, но я так и не смог устранить сообщение "[010P6] 010P6: A row was received and ignored. java.io.IOException: JZ0EM: End of data." появляющееся при каждом запросе, однако все данные выгружаются.