SBT 1.3.x : How to set a custom artifactPattern - sbt

I have the follow task to publish a custom artifact (in this case a gz file) in ivy format to a remote artifactory.
val publishImageTask = publishImageKey := {
println("Publishing gz file ...")
val extracted = Project.extract(state.value)
Project.runTask(publish, extracted.append(List(
publishTo := Some("MyArtifactory" at "https://xxx/artifactory/"),
publishMavenStyle := false,
isSnapshot := true,
publishArtifact in Compile := false,
publishArtifact in Test := false,
organization := "com.example.my",
moduleName := "myproject",
crossPaths := false,
credentials += Credentials(credentialsFile),
description := "A gz file",
version := "1.0.0",
packagedArtifacts in publish := {
val gzFile = new File("/tmp/foo.tar.gz")
println(s"gzFile:$gzFile")
val artifact = Artifact(name="foo", `type` = "release", extension = "tar.gz")
Map(artifact -> gzFile)
}
), state.value), true)
}
The above task will try to publish to
https://xxx/artifactory/com/example/my/myproject/1.0.0/foo-1.0.0.tar.gz
It seems the above is using artifactPattern
[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]
In sbt, how to set a custom artifactPattern
[organization]/[module]/[revision]/[type]s/[artifact](-[classifier])-[revision].[ext]
so that the URL includes the type "release"
https://xxx/artifactory/com/example/my/myproject/1.0.0/releases/foo.tar-1.0.0.gz
Thanks in advance for any assistance !
Shing

It turns out that the artifactPattern could be specified in URLRepository, which extends Resolver. In instead of
publishTo := Some("MyArtifactory" at "https://xxx/artifactory/"),
use
val repoUrl = "https://xxx/artifactory/"
val resolver = URLRepository(
name = "DockerImageRepo",
patterns = Patterns(
ivyPatterns =Vector(s"${repoUrl}/[organization]/[module]/[revision]/[type]s/ivy-[revision].xml"),
artifactPatterns = Vector(s"${repoUrl}/[organization]/[module]/[revision]/[type]s/[artifact](-[classifier])-[revision].[ext]"),
isMavenCompatible = true,
descriptorOptional = false,
skipConsistencyCheck = true
)
)
publishTo := Option(resolver)

Related

Telegraf json v2 parsing

I'm trying to pick out the local_temperature property from a Zigbee TRV.
Here is my section from /etc/telegraf/telegraf.conf
[[inputs.mqtt_consumer]]
servers = ["tcp://127.0.0.1:1883"]
topics = [
"zigbee2mqtt/Home/+/Radiator",
]
data_format = "json_v2"
[[inputs.mqtt_consumer.json_v2]]
measurement_name = "temperature"
[[inputs.mqtt_consumer.topic_parsing]]
topic = "_/room/_"
[[inputs.mqtt_consumer.json_v2.field]]
path = "local_temperature"
type = "float"
Error from /var/log/syslog
Feb 21 11:03:07 mini31 telegraf[23428]: 2022-02-21T11:03:07Z E! [inputs.mqtt_consumer] Error in plugin: metric parse error: expected tag at 1:36: "{\"battery\":97,\"boost_heating\":\"OFF\",\"boost_heating_countdown\":0,\"boost_heating_countdown_time_set\":300,\"child_lock\":\"UNLOCK\",\"current_heating_setpoint\":8,\"eco_mode\":\"OFF\",\"eco_temperature\":12,\"linkquality\":110,\"local_temperature\":17.5,\"local_temperature_calibration\":-2,\"max_temperature\":24,\"min_temperature\":8,\"position\":25,\"preset\":\"programming\",\"programming_mode\":\"09:00/19°C 12:00/13°C 14:00/19°C 17:00/8°C 06:00/8°C 12:00/8°C 14:30/8°C 17:30/8°C 06:00/8°C 12:30/8°C 14:30/8°C 18:30/8°C\",\"window\":\"CLOSED\",\"window_detection\":\"OFF\"}"
What does it even mean?
[[inputs.mqtt_consumer]]
servers = ["tcp://127.0.0.1:1883"]
topics = [
"zigbee2mqtt/Home/+/Radiator",
]
data_format = "json_v2"
[[inputs.mqtt_consumer.json_v2]]
measurement_name = "temperature"
[[inputs.mqtt_consumer.topic_parsing]]
topic = "zigbee2mqtt/Home/+/Radiator"
tags = "_/_/room/_"
[[inputs.mqtt_consumer.json_v2.field]]
path = "local_temperature"
rename = "temperature"
type = "float"
[[inputs.mqtt_consumer.json_v2]]
measurement = "valve"
[[inputs.mqtt_consumer.json_v2.field]]
path = "position"
rename = "valve"
type = "float"

Why is the variable modified when nginx Lua processes the request?

I just started studying Lua.
Every time I request, I want to check the name parameter in the request parameter. However, it is actually found that the self.name has changed occasionally.
For example,
request A with params: request_id = 123 & name = ABC,
request B with params: request_id = 321 & name = EFG,
in the log, I found that there are requests_id = 123, but name = EFG.
Why is that? Is my class incorrectly written?
Here is the sample code:
main.lua:
local checker = require "checker"
local ch = checker:new()
if ch:check_name() then
ngx.header["Content-Type"] = "application/json"
ngx.status = ngx.HTTP_FORBIDDEN
ngx.exit(ngx.HTTP_FORBIDDEN)
end
checker.lua:
local utils = require "utils"
local _M = {}
function _M:new()
local o = {}
setmetatable(o, self)
self.__index = self
self.args = utils.get_req_args() or {}
local name = self.args["name"] or ""
local request_id = self.args["request_id"] or ""
self.name = name
return o
end
function _M:check_name()
ngx.log(ngx.ERR, "request_id: ", self.request_id, " name: ", self.name)
-- do some check ...
end
utils.lua
local json = require "cjson"
local _M = {}
function _M.new(self)
return self
end
function _M.get_req_args()
-- GET
local args = nil
if ngx.var.request_method == "GET" then
args = ngx.req.get_uri_args()
-- POST
elseif ngx.var.request_method == "POST" then
ngx.req.read_body()
local data = ngx.req.get_body_data()
args = json.decode(data)
end
return args
end

R crashing with segfault when calling a function sourced with reticulate

I'm trying to write an R package with a function to send emails using python's smtplib module. The function works when I source it directly or with devtools::load_all(), but crashes R when I library my package and call the function.
I was using the mailR package, which uses java to send emails but I'm having issues after upgrading the version of java. I decided to write a quick package to replace it with a python version. Everything worked as expected until I installed it with devtools::install_local() and then tried calling the function. I've not got much experience with python, I feel like it might have something to do with how I'm importing the python modules, I tried moving the imports inside the function but that didn't help.
This is the python function that I'm sourcing with reticulate:
import smtplib
import re
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import COMMASPACE, formatdate
def py_sendmail(send_from, send_to, subject,
text_body = None, html_body = None,
inline = False, authenticate = False, ssl = False,
smtp_server = None, port = 587, username = None,
password = None, send = True, attach_files = None,
debug = False):
img_content = []
msg = MIMEMultipart('related')
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
if inline == True:
img_re = re.compile("<img(?:.+?)src\s*=\s*(?P<quote>['\"])(?P<imgurl>.*?)(?P=quote)")
imgs = img_re.findall(html_body)
img_cnt = 1
for(q, imgurl) in imgs:
fp = open(imgurl, 'rb')
msg_img = MIMEImage(fp.read())
fp.close()
img_id = "image" + str(img_cnt)
msg_img.add_header("Content-ID", "<"+img_id+">")
img_content.append(msg_img)
html_body = re.sub(imgurl, "cid:"+img_id, html_body)
img_cnt = img_cnt + 1
if text_body is not None and html_body is not None:
msgAlt = MIMEMultipart('alternative')
msg.attach(msgAlt)
msgAlt.attach(MIMEText(text_body, 'plain'))
msgAlt.attach(MIMEText(html_body, 'html'))
elif text_body is not None:
msg.attach(MIMEText(text_body, 'plain'))
elif html_body is not None:
msg.attach(MIMEText(html_body, 'html'))
if attach_files is not None:
for f in attach_files or []:
with open(f, 'rb') as fil:
part = MIMEApplication(
fil.read(),
Name=basename(f)
)
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
if len(img_content) > 0:
for img in img_content:
msg.attach(img)
if send == True:
if ssl == True:
server = smtplib.SMTP_SSL(smtp_server, port)
else:
server = smtplib.SMTP(smtp_server, port)
if authenticate == True:
server.login(username, password)
x = server.sendmail(send_from, send_to, msg.as_string())
server.quit()
return x == {}
else:
return msg.as_string()
It should send an email and it does when sourced into the global environment or when loaded with devtools::load_all(). But if I install it with devtools::install_local() and library it, it crashes R. When I run it in RStudio it crashes without explanation, when I run it from the command line i get this:
> library(pymailr)
> pymailr:::py_sendmail("<from_address>", "<to_address>", "Test",
+ text_body = "Testing", html_body = "<h1>Testing</h1>",
+ inline = FALSE, authenticate = TRUE, ssl = TRUE,
+ smtp_server = "<smtp_server>", port = 465, username = "<user_name>",
+ password = "<password>", send = TRUE)
*** caught segfault ***
address (nil), cause 'memory not mapped'
Traceback:
1: py_call_impl(callable, dots$args, dots$keywords)
2: pymailr:::py_sendmail("<from_address>", "<to_address>", "Test", text_body = "Testing", html_body = "<h1>Testing</h1>", inline = FALSE, authenticate = TRUE, ssl = TRUE, smtp_server = "<smtp_server>", port = 465, username = "<username>", password = "<password>", send = TRUE)

Where are the Kamon Counters?

I am learning how to do instrumentation using Kamon library.
This is my build.sbt
libraryDependencies ++= Seq(
"io.kamon" %% "kamon-core" % "0.6.7"
)
This is my plugins.sbt (in project folder)
addSbtPlugin("io.kamon" % "sbt-aspectj-runner" % "1.0.1")
This is my code
import kamon.Kamon
object KamonTest extends App {
Kamon.start()
val counter = Kamon.metrics.counter("foo")
1 to 100000 foreach { x =>
Thread.sleep(10)
counter.increment()
}
readLine()
print("press any key to exit")
readLine()
Kamon.shutdown()
}
Now when I run this app and run jmc and then go inside the MBEAN browser. I see this
So I cannot find the counter "foo" which I defined in my code.
I was able to solve the issue by the help of the gitter channel of Kamon
In order to publish to JMX console, we need the following two dependencies more in build.sbt
"io.kamon" %% "kamon-scala" % "0.6.7",
"io.kamon" %% "kamon-jmx" % "0.6.7"
We also need the following entries in application.conf
kamon.jmx {
subscriptions {
histogram = [ "**" ]
min-max-counter = [ "**" ]
gauge = [ "**" ]
counter = [ "**" ]
trace = [ "**" ]
trace-segment = [ "**" ]
system-metric = [ "**" ]
http-server = [ "**" ]
kamon-mxbeans = [ "**" ]
}
}
kamon.modules {
kamon-mxbeans {
auto-start = yes
requires-aspectj = no
extension-class = "kamon.jmx.extension.JMXMetricImporter"
}
}
kamon.kamon-mxbeans {
mbeans = [
{ "name": "example-mbean", "jmxQuery": "example:type=myBean,name=*",
"attributes": [
{ "name": "foo", "type": "counter" }
]
}
],
identify-delay-interval-ms = 1000,
identify-interval-ms = 1000,
value-check-interval-ms = 1000
}

How to link Java API classes using apiMappings?

How do you link to Java classes in sbt using apiMappings? This is my code below which works for various dependencies, but I'm unclear how to link to Java standard library classes?
apiMappings ++= {
def findManagedDependency(organization: String, name: String): Option[File] = {
(for {
entry <- (fullClasspath in Runtime).value ++ (fullClasspath in Test).value
module <- entry.get(moduleID.key) if module.organization == organization && module.name.startsWith(name)
} yield entry.data).headOption
}
val links = Seq(
findManagedDependency("org.scala-lang", "scala-library").map(d => d -> url(s"http://www.scala-lang.org/api/$scalaVsn/")),
findManagedDependency("com.typesafe.akka", "akka-actor").map(d => d -> url(s"http://doc.akka.io/api/akka/$akkaVersion/")),
findManagedDependency("com.typesafe", "config").map(d => d -> url("http://typesafehub.github.io/config/latest/api/")),
findManagedDependency("com.fasterxml.jackson.core", "jackson-core").map(d => d -> url("http://fasterxml.github.io/jackson-core/javadoc/2.3.1/")),
findManagedDependency("io.spray", "spray-http").map(d => d -> url("http://spray.io/documentation/1.1-SNAPSHOT/api/")),
findManagedDependency("io.spray", "spray-routing").map(d => d -> url("http://spray.io/documentation/1.1-SNAPSHOT/api/")),
findManagedDependency("org.slf4j", "slf4j-api").map(d => d -> url("http://www.slf4j.org/api/")),
findManagedDependency("com.typesafe.akka", "akka-testkit").map(d => d -> url(s"http://doc.akka.io/api/akka/$akkaVersion/")),
findManagedDependency("org.specs2", "specs2").map(d => d -> url(s"http://etorreborre.github.io/specs2/api/SPECS2-$specs2Version/"))
)
links.collect { case Some(d) => d }.toMap
}
Use the solution from How to link classes from JDK into scaladoc-generated doc?, i.e. add the following to apiMappings:
apiMappings += (
file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") ->
url("http://docs.oracle.com/javase/8/docs/api")
)
and fixJavaLinksTask task will do the rest with the following in build.sbt:
import scala.util.matching.Regex.Match
autoAPIMappings := true
// builds -doc-external-doc
apiMappings += (
file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") ->
url("http://docs.oracle.com/javase/8/docs/api")
)
lazy val fixJavaLinksTask = taskKey[Unit](
"Fix Java links - replace #java.io.File with ?java/io/File.html"
)
fixJavaLinksTask := {
println("Fixing Java links")
val t = (target in (Compile, doc)).value
(t ** "*.html").get.filter(hasJavadocApiLink).foreach { f =>
println("fixing " + f)
val newContent = javadocApiLink.replaceAllIn(IO.read(f), fixJavaLinks)
IO.write(f, newContent)
}
}
val fixJavaLinks: Match => String = m =>
m.group(1) + "?" + m.group(2).replace(".", "/") + ".html"
val javadocApiLink = """\"(http://docs\.oracle\.com/javase/8/docs/api/index\.html)#([^"]*)\"""".r
def hasJavadocApiLink(f: File): Boolean = (javadocApiLink findFirstIn IO.read(f)).nonEmpty
fixJavaLinksTask <<= fixJavaLinksTask triggeredBy (doc in Compile)
You may find my answer to this question what you are looking for.
This main difference between that answer and the other answer posted here is that the location of rt.jar is determined from the runtime, and not hard coded.

Resources